UVA10891

/*
题意:n 个数 AB两个人轮流从左或右端取连续的数,
每个人都按最优策略取,A先取,问最后A 比 B 多多少 。
区间DP。 
用f[i][j]表示区间 i-j 能取的数的总和是多少, 
如果从左端取,f[i][i+k]=max(f[i][i+k], (sum[i+k]-sum[i-1])-f[i][j]); 其中j∈[i,i+k) 。 
则右端, f[i][i+k]=max(f[i][i+k], (sum[i+k]-sum[i-1])-f[j][j+k]); 其中j∈[i+1,i+k] .
再与取一整段比较取最优。
辣么,A比B多 f[1][n]- (f[1][n]-sum[n]) 即 2 * f[1][n] - sum[n]
*/ 
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int sum[110],a[110];
int f[110][110];
int main()
{
    int n;
    while(scanf("%d",&n)!=EOF && n)
    {
        memset(sum,0,sizeof(sum));
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            sum[i]=sum[i-1]+a[i];
        }    
        int s=0;
        memset(f,-0x3f,sizeof(f));    
        for(int i=1;i<=n;i++)
            f[i][i]=a[i];
        for(int k=1;k<n;k++)
            for(int i=0;i+k<=n;i++)                                                                                                                                                                                                                                                    
            {
                s=sum[i+k]-sum[i-1];  
                for(int j=i;j<i+k;j++)                 
                    f[i][i+k] = max(f[i][i+k], s-f[i][j]);
                for(int j=i+1;j<=i+k;j++)  
                    f[i][i+k] = max(f[i][i+k], s-f[j][i+k])    ;
                f[i][i+k] = max(s,f[i][i+k]);                         
            }
         printf("%d\n", 2 * f[1][n] - sum[n]);
    }
    return 0;
}

 

posted @ 2015-10-23 21:13  Ember  阅读(510)  评论(0编辑  收藏  举报