Cheat in the Game - poj3688 - 博弈+dp

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 MW 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张牌之和,
  1. n为偶数时,{先手一张,后手一张}循环,后手胜
  2. n为奇数时,{先手一张,后手一张}循环,先手胜
  3. 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);
	}
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值