UVA 10891 Game of Sum(经典区间dp)

来源:互联网 发布:网络游戏同步算法 编辑:程序博客网 时间:2024/06/02 10:51

这道题的题意就是一段数字,两个人,每个人交替取数字,每次只能从左或者右取一个或者多个数字,保证自己拿到的数字之和最大,前提是两个人都足够聪明,那么,最后的差a-b等于多少。

思路就是: dp(i,i+k)表示的是在i~i+k中能得到的最大值,转移的思路是,在这一段中会分给两个人,所以dp[i][i+k]=sum[i][j]-min(dp[i][i+1].......... dp[i][i+k])就是找这中间所有的子序列中最少的就好

AC代码:

/* ***********************************************Author        :yzkAcceptedCreated Time  :2016/5/20 19:18:44TASK  :ggfly.cppLANG          :C++************************************************ */#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <vector>#include <queue>#include <set>#include <map>#include <string>#include <cmath>#include <cstdlib>#include <ctime>#include <stack>using namespace std;const int maxn=110;const int inf=1<<27;int a[maxn],A[maxn],dp[maxn][maxn];int main(){    //freopen("in.txt","r",stdin);    //freopen("out.txt","w",stdout);    int n,i,j,k;while(~scanf("%d",&n)&&n){memset(A,0,sizeof(A));for(i=0;i<=n;i++)for(j=0;j<=n;j++)dp[i][j]=-inf;for(i=1;i<=n;i++){scanf("%d",&a[i]);A[i]=A[i-1]+a[i];}for(i=1;i<=n;i++)dp[i][i]=a[i];for(k=1;k<n;k++){for(i=1;i+k<=n;i++){int sum=A[i+k]-A[i-1];for(j=i;j<i+k;j++)if(sum-dp[i][j]>dp[i][i+k])dp[i][i+k]=sum-dp[i][j];for(j=i+1;j<=i+k;j++)if(sum-dp[j][i+k]>dp[i][i+k])dp[i][i+k]=sum-dp[j][i+k];if(sum>dp[i][i+k])dp[i][i+k]=sum;}}printf("%d\n",2*dp[1][n]-A[n]);}    return 0;}



0 0