• 2013 吉林通化邀请赛 Play Game 记忆化搜索


    dp[ba][ta][bb][tb]表示a堆牌从下面拿了ba张,从上面拿了ta张。b堆牌从下面拿了bb张,从上面拿了tb张。当前玩家能得到的最大的分数。

    扩展方式有4种,ba+1,ta+1,bb+1,tb+1,用当前剩下牌的总分减掉它,取最大值,就是当前玩家的最高分。

    记忆化搜索

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    int a[30];
    int b[30];
    int sum;
    int dp[21][21][21][21],n,maxn;
    inline int cal_max(int a,int b,int c)
    {
        return max(max(a,b),c);
    }
    int dfs(int ba,int ta,int bb,int tb,int sums)
    {
        if(ba+ta==n&&bb+tb==n) return 0;
        if(dp[ba][ta][bb][tb]) return dp[ba][ta][bb][tb];
        int maxn=0;
        if(ba+ta<n)
        {
            maxn=cal_max(maxn,sums-dfs(ba+1,ta,bb,tb,sums-a[ba+1]),sums-dfs(ba,ta+1,bb,tb,sums-a[n-ta]));
        }
        if(bb+tb<n)
        {
            maxn=cal_max(maxn,sums-dfs(ba,ta,bb+1,tb,sums-b[bb+1]),sums-dfs(ba,ta,bb,tb+1,sums-b[n-tb]));
        }
        dp[ba][ta][bb][tb]=maxn;
        return maxn;
    }
    int main()
    {
        int cas;
        scanf("%d",&cas);
        while(cas--)
        {
            sum=0;
            scanf("%d",&n);
            memset(dp,0,sizeof(dp));
            for(int i=1;i<=n;i++)
            {
                scanf("%d",&a[i]);
                sum+=a[i];
            }
            for(int i=1;i<=n;i++)
            {
                scanf("%d",&b[i]);
                sum+=b[i];
            }
            printf("%d
    ",dfs(0,0,0,0,sum));
        }
        return 0;
    }
    


  • 相关阅读:
    实现IEnumberable接口和IEnumberator
    XAML-1
    Java基础00-Java概述1
    详解Lombok中的@Builder用法
    stream之map的用法
    stream之forEach的用法
    Java中map.getOrDefault()方法的使用
    BiPredicate的test()方法
    Function.identity()
    java 8 lamda Stream的Collectors.toMap 参数
  • 原文地址:https://www.cnblogs.com/riskyer/p/3279909.html
Copyright © 2020-2023  润新知