【POJ 3688 Cheat in the Game】+ dp + 巴什博弈

来源:互联网 发布:python参考手册 第5版 编辑:程序博客网 时间:2024/06/03 07:57

Description

Alice and Bob are playing a game. At the beginning, the judge takes out a stone pile of W stones and a black box containing N cards. Every card has a number Ai on it. Alice and Bob takes turns to draw a card from the box. Of course, they will not know the number until they draw the card out of the box. The player then takes away Ai stones from the pile if it is possible. If there are not enough stones, the player draws a card again. The winner is the player who takes away the last stone. Once the box gets empty, they brings back all cards and stones and play the game again until there is a winner.

Now your best friend Alice begs you, the judge, to help her cheat in the game. You have already known the number of cards in the box and their numbers. Given a integer M, You want to know how many values, less or equal to M, W can take so that you can make sure Alice will be the winner of the game.

Input

There are several test cases.
The first line of each test case contains two integers N (1 ≤ N ≤ 10000) and M (1 ≤ M ≤ 100000).
The second line contains N integers Ai (1 ≤ Ai ≤ M). The input ends with two zeros

Output

For each test case output how many values you can choose for W so that Alice will be the winner without fail.

Sample Input

3 8
1 5 7
0 0
Sample Output

3

只有当抽牌的可能数为奇数时第一个人才必胜 :

dp[j][0] 表示当石头重量为 j 时抽牌方案数可能为偶数;
dp[j][1] 表示当石头重量为 j 时抽牌方案书可能为奇数;

当dp[j][0]不存在,dp[j][1]存在时,先手才必胜;

AC代码 :

#include<cstdio>#include<cstring>using namespace std;int pa[10011],dp[100011][3];int main(){    int N,M,i,j;    while(scanf("%d%d",&N,&M)!=EOF){    if(N == 0 && M == 0)        break;    memset(dp,0,sizeof(dp));    for(i = 1 ; i <= N ; i++)        scanf("%d",&pa[i]);    for(i = 1 ; i <= N ; i++){        for(j = M ; j >= pa[i] ; j--){            if(dp[j - pa[i]][0]) // 之前是偶数次                 dp[j][1] = 1;            if(dp[j - pa[i]][1]) // 之前是奇数次                 dp[j][0] = 1;        }        dp[pa[i]][1] = 1; // 仅此一次     }    int ans = 0;    for(i = 1 ; i <= M ; i++)        if(dp[i][1] && !dp[i][0])            ans++; // 必胜方案数     printf("%d\n",ans);   }    return 0;}
0 0
原创粉丝点击