您的位置:首页 > 其它

UVA10891

2015-10-23 21:13 197 查看
/*
题意: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]
- (f[1]
-sum
) 即 2 * f[1]
- sum

*/
#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]
- sum
);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: