码迷,mamicode.com
首页 > 其他好文 > 详细

09_Sum游戏(UVa 10891 Game of Sum)

时间:2015-04-02 20:31:16      阅读:229      评论:0      收藏:0      [点我收藏+]

标签:

问题来源:刘汝佳《算法竞赛入门经典--训练指南》 P67 例题28:

问题描述:有一个长度为n的整数序列,两个游戏者A和B轮流取数,A先取,每次可以从左端或者右端取一个或多个数,但不能两端都取,所有数都被取完时游戏结束,然后统计每个人取走的所有数字之和作为得分,两人的策略都是使自己的得分尽可能高,并且都足够聪明,求A的得分减去B的得分的结果。

问题分析:1.设dp[i][j]表示从第i第j的数的序列中,双方都采取最优策略的前提下,先手得分的最大值

       2.若求dp[i][j],我们可以枚举从左边(或者右边)取多少个数,并求枚举过程中dp[i][j]的最大值,则有状态转移方程

          dp[i][j] = sum[i][j] - Min{dp[i+1][j],dp[i+2][j],...,dp[j][j],  dp[i][i],dp[i][i+1],...,dp[i][j-1]}

      (其中sum[i][j] 表示从i到j的序列和)

例题链接:...

例题:UVa 10891

;

代码:

 1 #include "stdio.h"
 2 #include "string.h"
 3 #define N 105
 4 int a[N];
 5 int sum[N];
 6 int dp[N][N],mark[N][N];
 7 
 8 int inline Min(int a,int b) { return a<b?a:b; }
 9 
10 int DP(int i,int j) //记忆化搜索
11 {
12     if(mark[i][j])
13         return dp[i][j];
14     mark[i][j] = 1;
15     int m = 0;  //全部取光
16     for(int k=i+1; k<=j; k++)
17         m = Min(m,DP(k,j));
18     for(int k=j-1; k>=i; k--)
19         m = Min(m,DP(i,k));
20     dp[i][j] = sum[j] - sum[i-1] - m;
21     return dp[i][j];
22 }
23 
24 int main()
25 {
26     int n;
27     int i,j,k;
28     while(scanf("%d",&n) == 1)
29     {
30         for(i=1; i<=n; i++)
31             scanf("%d",&a[i]);
32         memset(sum,0,sizeof(sum));
33         for(i=1; i<=n; i++)
34             sum[i] = sum[i-1] + a[i];
35         memset(dp,0,sizeof(dp));
36         memset(mark,0,sizeof(mark));  //标记初始化
37         printf("%d\n",2*DP(1,n)-s[n]);
38     }
39     return 0;
40 }

 

09_Sum游戏(UVa 10891 Game of Sum)

标签:

原文地址:http://www.cnblogs.com/ruo-yu/p/4388130.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!