您的位置:首页 > 其它

LightOJ1031 Easy Game(区间DP)

2016-01-12 18:14 309 查看
我可能真想不到这题是区间DP,不过知道是区间DP想了下就AC了。

dp[i][j]表示局面为ai...aj先手能获得与后手得分的最大差值

那么转移到当前状态就是枚举中间的位置,分成两边,其中一边先手全部取另一边就是新的局面,后手变成新的先手的局面,而后手也会采取最优策略也会尽量让剩下这个局面差值最大。方程如下:

dp[i][j] = max( sum[i][j] , sum[i][k]-dp[k+1][j] , sum[k+1][j]-dp[i][k] ) (i<=k<j)

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define INF (1<<29)
int d[111][111];
int main(){
int t,n,s[111]={0};
scanf("%d",&t);
for(int cse=1; cse<=t; ++cse){
scanf("%d",&n);
for(int i=1; i<=n; ++i) scanf("%d",s+i),s[i]+=s[i-1];
for(int i=1; i<=n; ++i){
for(int j=1; j<=n; ++j) d[i][j]=-INF;
d[i][i]=s[i]-s[i-1];
}
for(int len=1; len<n; ++len){
for(int i=1; i+len<=n; ++i){
d[i][i+len]=s[i+len]-s[i-1];
for(int j=i; j<i+len; ++j) d[i][i+len]=max(d[i][i+len],s[j]-s[i-1]-d[j+1][i+len]);
for(int j=i+len; j>i; --j) d[i][i+len]=max(d[i][i+len],s[i+len]-s[j-1]-d[i][j-1]);
}
}
printf("Case %d: %d\n",cse,d[1]
);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: