zoukankan      html  css  js  c++  java
  • Light OJ 1031

    题目大意:
    给你一个n,代表n个数字,现在有两个选手,选手A,B轮流有有一次机会,每个选手一次可以得到一个或者多个数字,从左侧或者右侧,但是不能同时从两边取数字,当所有的数字被取完,那么游戏结束。然后计算每个选手所得到数字的总和,每个选手都尽量让自己的分数比较多,选手A先开始取数。假设每个选手取得数字都是最优的,问A最多比B多多少分数,、
    题目分析:
    记忆化搜索,区间DP。
    dp[该谁取了][左区间L][右区间] = 所能取到的最大值。
    做下简单的预处理,得到区间L-R之间的和。
    然后状态转移 dp[cur][L][R] = max(dp[cur][L][R], sum[L][K] + sum[K+1][R] - dp[cur^1][L][K] );
    然后再反过来做一次DP, 总体求最大就行了。
     
    =====================================================================================================
     
     
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<cmath>
    #include<queue>
    #include<vector>
    #include<map>
    using namespace std;
    typedef long long LL;
    const int INF = 1e9+7;
    const int MAXN = 255;
    int a[MAXN], dp[2][MAXN][MAXN];
    int sum[MAXN];
    int DFS(int cur,int L,int R)
    {
        if( dp[cur][L][R] != -INF )
            return dp[cur][L][R];
        if(L > R)
            return 0;
        if(L == R)
            return dp[cur][L][R] = a[L];
    
    
        for(int i=L; i<=R; i++)
        {
            int A = sum[i]-sum[L-1];///所选取的区间
            int B = sum[R]-sum[i];///丢弃的区间总和
            dp[cur][L][R] = max(dp[cur][L][R],A + B - DFS(cur^1,i+1,R) );
        }
        for(int i=R; i>=L; i--)
        {
            int A = sum[R] - sum[i-1];
            int B = sum[i-1] - sum[L-1];
            dp[cur][L][R] = max(dp[cur][L][R],A + B - DFS(cur^1,L,i-1));
        }
        return dp[cur][L][R];
    }
    
    int main()
    {
        int T, cas = 1, n;
        scanf("%d", &T);
        while(T --)
        {
            scanf("%d", &n);
            memset(sum, 0, sizeof(sum));
    
            for(int i=0; i<=n; i++)
            for(int j=0; j<=n; j++)
            dp[0][i][j] = dp[1][i][j] = -INF;
    
            for(int i=1; i<=n; i++)
            {
                scanf("%d", &a[i]);
                sum[i] = sum[i-1] + a[i];
            }
            int ans = DFS(0, 1, n);
            printf("Case %d: %d
    ", cas++, 2*ans - sum[n]);
        }
    
        return 0;
    }
    /*
    
    3
    
    3
    1 2 3
    */
  • 相关阅读:
    刷新或关闭时调用onbeforeunload
    单词换行问题
    PhpStorm提高效率的使用方法及设置
    高质量代码编写
    数组去重
    HMTL5 本地数据库
    Html5 本地存储
    php array(object) 与xml相互转换
    pwnable.kr之leg
    文件上传漏洞及其绕过
  • 原文地址:https://www.cnblogs.com/chenchengxun/p/4911616.html
Copyright © 2011-2022 走看看