-
描述
-
有一个长度为n的整数序列,A和B轮流取数,A先取,每次可以从左端或者右端取一个数,所有数都被取完时游戏结束,然后统计每个人取走的所有数字之和作为得分,两人的策略都是使自己的得分尽可能高,并且都足够聪明,求A的得分减去B的得分的结果。
-
输入
- 输入包括多组数据,每组数据第一行为正整数n(1<=n<=1000),第二行为给定的整数序列Ai(-1000<=Ai<=1000)。 输出
- 对于每组数据,输出A和B都采取最优策略的情况下,A的得分减去B的得分的结果。 样例输入
-
3 1 2 3 4 2 4 5 3
样例输出
-
2 0
来源
- Yougth原创 上传者
-
TC_杨闯亮
ps:区间动规。。本题需要有两个状态表。。这一局的dp值等于上一局的区间的总值-上一局对手的dp值+新增端点的值、而上一局的区间的总值+新增端点的值=这一局区间总值、而区间分割只有两种情况
例如:1 2 3 4可以分为两种情况:
1 234
123 4
所以它每一局的dp值的改变方式有dp[i][j]=maxx(w[i][j]-dp[i-1][j],w[i][j]-dp[i-1][j+1]);
代码如下:
#include<stdio.h> #include<string.h> using namespace std; int dp[1020][1020],w[1020][1020]; int maxx(int a,int b) { return a>b?a:b; } int main() { int n; int a[1020]; while(~scanf("%d",&n)) { memset(dp,0,sizeof(dp)); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); dp[1][i]=a[i]; w[1][i]=a[i]; } for(int i=2;i<=n;i++) { for(int j=1;j<=n-i+1;j++) { w[i][j]=w[i-1][j]+w[1][i+j-1];//记录每一个区间的和。 //printf("!!!%d\n",w[i][j]); } } for(int i=2;i<=n;i++) { for(int j=1;j<=n-i+1;j++) { dp[i][j]=maxx(w[i][j]-dp[i-1][j],w[i][j]-dp[i-1][j+1]);//增头或增尾的两种情况 //printf("###%d\n",dp[i][j]); } } int z=2*dp[n][1]-w[n][1]; printf("%d\n",z); } }
nyoj 1030 Yougth's Game[Ⅲ] 区间动规
最新推荐文章于 2018-10-05 20:47:12 发布