POJ 3688 Cheat in the Game
2016-07-29 21:56
381 查看
传送门:http://poj.org/problem?id=3688
题意:金手指:有俩人玩一个取石子的游戏,你是裁判。游戏中有W块石头和N张卡片,卡片上分别写着数字Ai。玩家随机抽走一张卡片,按卡片上的数字从石头堆中取走相应数量的石头,如果石头不够,玩家重新抽卡片,取走最后一块石头的玩家获胜;如果石头堆为空仍然未分出胜负,则拿回所有石头和卡片重新开始。
现在先手玩家贿♂赂了你,请你帮他构造必胜条件。游戏中的卡片是固定的,但W可供你操作。问有多少小于或等于M的W满足要求。
分析:
如果W只能表示成特定的n张卡片上的数字之和,那么:
当n为偶数时,{先手一张,后手一张}循环n/2次拿完石头,后手玩家必胜。
当n为奇数时,{先手一张,后手一张}循环n/2 + 1次拿完石头,先手玩家必胜。
如果W既可以表示成奇数张卡片数字之和,也可以表示成偶数张卡片数字之和,则两人都可能获胜;或者说没有必胜决策。
如果W既无法表示成奇数张卡片数字之和,也无法表示成偶数张卡片数字之和,则W无法用卡片取完,两人会一直玩到天荒地老,你这个裁判就变成了灯泡,而且是长明灯。
所以对题目有用的只有第一个如果分支。
这里有两份代码,一份wrong,一份ac,若能找出不同,你就彻底明白这道题了
wrong code:
AC code:
题意:金手指:有俩人玩一个取石子的游戏,你是裁判。游戏中有W块石头和N张卡片,卡片上分别写着数字Ai。玩家随机抽走一张卡片,按卡片上的数字从石头堆中取走相应数量的石头,如果石头不够,玩家重新抽卡片,取走最后一块石头的玩家获胜;如果石头堆为空仍然未分出胜负,则拿回所有石头和卡片重新开始。
现在先手玩家贿♂赂了你,请你帮他构造必胜条件。游戏中的卡片是固定的,但W可供你操作。问有多少小于或等于M的W满足要求。
分析:
推理与动态规划算法
如果W只能表示成特定的n张卡片上的数字之和,那么:当n为偶数时,{先手一张,后手一张}循环n/2次拿完石头,后手玩家必胜。
当n为奇数时,{先手一张,后手一张}循环n/2 + 1次拿完石头,先手玩家必胜。
如果W既可以表示成奇数张卡片数字之和,也可以表示成偶数张卡片数字之和,则两人都可能获胜;或者说没有必胜决策。
如果W既无法表示成奇数张卡片数字之和,也无法表示成偶数张卡片数字之和,则W无法用卡片取完,两人会一直玩到天荒地老,你这个裁判就变成了灯泡,而且是长明灯。
所以对题目有用的只有第一个如果分支。
这里有两份代码,一份wrong,一份ac,若能找出不同,你就彻底明白这道题了
wrong code:
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <string> #include <algorithm> using namespace std; int main() { int n,m; int num[10005]; bool dp[100010][2]; while(scanf("%d %d",&n,&m)==2&&n) { memset(num,0,sizeof(num)); memset(dp,false,sizeof(dp)); for(int i=0;i<n;i++) { scanf("%d",&num[i]); } sort(num,num+n); int i,j; int ans = 0; for(i=0;i<n;i++) dp[num[i]][1] = true; for( i=1;i<n;i++) { for(j=m;j>num[i];j--) { if(dp[j-num[i]][0]) dp[j][1] = true; if(dp[j-num[i]][1]) dp[j][0] = true; } } for(i=1;i<=m;i++) { if(dp[i][1]&&(!dp[i][0]))ans++; } printf("%d\n",ans); } return 0; }
AC code:
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <string> #include <algorithm> using namespace std; int main() { int n,m; int num[10005]; bool dp[100010][2]; while(scanf("%d %d",&n,&m)==2&&n) { memset(num,0,sizeof(num)); memset(dp,false,sizeof(dp)); for(int i=0;i<n;i++) { scanf("%d",&num[i]); } //sort(num,num+n);//排不排序对这道题结果不影响,自己体会 int i,j; int ans = 0; for( i=0;i<n;i++) { for(j=m;j>num[i];j--) { if(dp[j-num[i]][0]) dp[j][1] = true; if(dp[j-num[i]][1]) dp[j][0] = true; } dp[num[i]][1] = true; } for(i=1;i<=m;i++) { if(dp[i][1]&&(!dp[i][0]))ans++; } printf("%d\n",ans); } return 0; }
相关文章推荐
- POJ 3688 Cheat in the Game (博弈 dp)
- POJ 3688 Cheat in the Game 已翻译
- POJ 3688 Cheat in the Game(作弊博弈)
- 【POJ 3688 Cheat in the Game】+ dp + 巴什博弈
- POJ 3688 Cheat in the Game(博弈论)
- poj1289 The Cat in the Hat
- The same plan as .Game Framework in USA [flyinsky]
- Poj 2996 Help Me with the Game
- poj 1027 The Same Game
- POJ 2996, Help Me with the Game
- POJ-2388 who's in the middle
- poj1027——The Same Game
- POJ--2388 Who's in the Middle (续)
- poj 2388 Who's in the Middle
- POJ2996-Help Me with the Game
- POJ2388-Who's in the Middle
- poj 2286 The Rotation Game 迭代加深
- Who's in the Middle--POJ 2388
- POJ--2388 Who's in the Middle
- 【原】 POJ 2388 Who's in the Middle 中位数 解题报告