POJ 2068 Nim

链接:

http://poj.org/problem?id=2068

题意:

传统的Nim游戏由两名玩家进行,在一堆石头中,双方轮流取走任意合法数量块石头,取走最后一块石头的玩家落败。

多人Nim游戏将参赛人数拓展至两个队伍,每支队伍有n名队员交错入座,单次分别能最多取走Mi块石头,取走S块石头中的最后一块的队伍失败,

求第一支队伍是否有必胜策略?

题解:

dp[i][j]表示第i个人取,还有j块石头 。

当j为0的时候,没有石头,这时候是胜,为1。

后继中有必败态的为必胜态。

代码:

31 int dp[30][10010];
32 int n, s, a[30];
33
34 int solve(int idx, int remain) {
35     if (dp[idx][remain] != -1) return dp[idx][remain];
36     if (remain == 0) return dp[idx][remain] = 1;
37     dp[idx][remain] = 0;
38     rep(i, 1, min(a[idx], remain) + 1)
39         if (!solve((idx + 1) % (2 * n), remain - i))
40             dp[idx][remain] = 1;
41     return dp[idx][remain];
42 }
43
44 int main() {
45     while (cin >> n, n) {
46         cin >> s;
47         rep(i, 0, 2 * n) cin >> a[i];
48         memset(dp, -1, sizeof(dp));
49         cout << solve(0, s) << endl;
50     }
51     return 0;
52 }
时间: 2024-08-11 07:20:23

POJ 2068 Nim的相关文章

POJ 2068 Nim#双人dp博弈

http://poj.org/problem?id=2068 #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; int dp[25][(1<<13)+5];//dp[i][j]表示轮到第i个人取时,剩j个石头 int n,s,m[25]; int DFS(int pos,int remain) { if(dp

poj 2068 Nim(博弈dp)

Nim Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 1403   Accepted: 791 Description Let's play a traditional game Nim. You and I are seated across a table and we have a hundred stones on the table (we know the number of stones exactly).

POJ 2068 Nim 组合游戏

题目大意:有一堆石子,两伙人,围在一起坐,坐的顺序是ABABABAB....每一个人最多能取a[i]个石子,取走最后一个石子的就输了.问谁能赢. 思路:朴素的组合游戏判定问题,这个题给了数据范围,可以进行记忆化搜索.f[i][j]为还剩下i个石子,到了第j个人的时候的状态,然后记忆化一下. CODE: #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #

POJ 2068 Nim (dp博弈)

题意: 共n轮,s个石头和两队人,两队人轮流拿,第i轮两队分别只能拿1~M[(2*i-1)%(2*n)]和1~M[(2*i)%(2*n)]个石头,拿到最后那个石头的队输: 就拿最后一组样例来说,循环中共3轮,共97个石头,第一轮两队分别拿不超过8个和7个石头,第二轮6个和5个,第三轮4个和3个,然后又是8个和7个...... Input n S M[1]  M[2] . . . M[2*n] 1 <= n <= 10, 1 <= Mi <= 16, and 1 <= S &l

POJ 2068

就是必胜点与必败点的计算而已.计算每一种情况.设st[i][j]为在第i个人剩下j个石头时的情况,拿它转移后的情况比较.可以到达必败点,则当前为必胜点.若只能到达必胜点,则当前点为必败点. 1 #include <iostream> 2 #include <cstdio> 3 using namespace std; 4 const int S=8330; 5 const int N=22; 6 7 int st[N][S]; 8 int s,n; 9 int MA[N]; 10

HDU 3404&amp;POJ 3533 Nim积(二维&amp;三维)

(Nim积相关资料来自论文曹钦翔<从"k倍动态减法游戏"出发探究一类组合游戏问题>) 关于Nim积计算的两个函数流程: 代码实现如下: int m[2][2]={0,0,0,1}; int Nim_Multi_Power(int x,int y) { if(x<2) return m[x][y]; int a=0; for(;;a++) if(x>=(1<<(1<<a))&&x<(1<<(1<<

[原博客] POJ 2975 Nim 统计必胜走法个数

题目链接题意介绍了一遍Nim取石子游戏,可以看上一篇文章详细介绍.问当前状态的必胜走法个数,也就是走到必败状态的方法数. 我们设sg为所有个数的Xor值.首先如果sg==0,它不可能有必胜走法,输出0. 对于任意一堆有a[i]个石子,若sg Xor a[i] <= a[i] ,那么我们就可以在a[i]里面取出sg Xor a[i]个石子,使得剩下石子Xor和为0,于是ans++.然后输出ans. 注意C/C++语言中^操作比<操作优先级低. #include<iostream> #

poj 2975 Nim(博弈)

Nim Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 5232   Accepted: 2444 Description Nim is a 2-player game featuring several piles of stones. Players alternate turns, and on his/her turn, a player’s move consists of removing one or mor

POJ 3537 Nim游戏

链接: http://poj.org/problem?id=3537 题意: 有个2人玩的游戏在一个规模为1*n的棋盘上进行,每次一个人选择一个地方画上'X',一旦某个人画上X后出现了连续3个X,那么这个人就赢了. 题解: 仔细思考一下我们发现,xxx的上一步只能是oxx,xox,xxo的其中一种,也就是说如果谁走出一步形成上述局面那么谁就必败. 再进一步说,如果你在第i个格子画x,那么i-1,i-2,i+1,i+2,都不可以画x,因为那样会必败. 这样题目就可以转化为,轮流画x,谁没有格子画x