Cheat in the Game
Time Limit: 6000MS | Memory Limit: 65536K | |
Total Submissions: 1270 | Accepted: 443 |
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
Hint
We say that Alice is surely to win if and only if the possibility that Alice wins is greater than zero and the possibility that Bob wins is zero. For the sample, W = 1, 5, 7.
Source
POJ Founder Monthly Contest – 2008.08.31, facer
题意:
W个石子,有N张卡片放在盒子里,每张上写着数字ai,A和B轮流抽卡片,按照卡片上的数去取石子,若石子数不够则,则抽下一张卡片,若是卡片抽完了,则把所有的卡片和石子复位,再来一局。谁抽到最后一个石子胜利。
现在A来找你作弊啦,因为你是裁判,知道每张牌的值,求石子的数量W的值(<=W)可以是多少,保证A胜。
思路:
- w能表示n张牌之和,
- n为偶数时,{先手一张,后手一张}循环,后手胜
- n为奇数时,{先手一张,后手一张}循环,先手胜
- n既能是奇数,又能是偶数,则先手、后手都可能胜
- w既不能表示奇数张牌之和,又不能表示偶数张牌之和,则无法用牌取完W,游戏进行到天荒地老~
dp[i][0]:=w值为i(有i个石子)时,能用偶数张牌表示的输赢,1->胜,0->败
dp[i][1]:=w值为i(有i个石子)时,能用奇数张牌表示的输赢,1->胜,0->败
dp[a[i]][1]=1;
if(dp[j-a[i]][0])dp[j][1]=1;
if(dp[j-a[i]][1])dp[j][0]=1;
判断A胜条件if(dp[i][1]&&!dp[i][0])
代码如下:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<vector>
#include<set>
#include<list>
using namespace std;
int a[10005],dp[100005][3];
int main(){
int n,m;
while(scanf("%d%d",&n,&m)!=EOF){
if(n+m==0)break;
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
}
sort(a,a+n);
memset(dp,0,sizeof(dp));
dp[a[0]][1]=1;
for(int i=1;i<n;i++){//i张卡片
for(int j=m;j>a[i];j--){//j块石头由几张卡片组成
if(dp[j-a[i]][0])dp[j][1]=1;
if(dp[j-a[i]][1])dp[j][0]=1;
}
dp[a[i]][1]=1;
}
int ans=0;
for(int i=a[0];i<=m;i++){
if(dp[i][1]&&!dp[i][0])ans++;
}
printf("%d\n",ans);
}
}