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; }