题意:有俩人玩一个取石子的游戏,你是裁判。游戏中有W块石头和N张卡片,卡片上分别写着数字ai。玩家随机抽走一张卡片,按卡片上的数字从石头堆中取走相应数量的石头,如果石头不够,玩家重新抽卡片,取走最后一块石头的玩家获胜;如果石头堆为空仍然未分出胜负,则拿回所有石头和卡片重新开始。现在先手玩家贿赂了你,请你帮他构造必胜条件。游戏中的卡片是固定的,但W可供你操作。问有多少小于或等于M的W满足要求
dp[i][1] = true表示石头数为i的情况可以由奇数张卡片组成
dp[i][0] = true表示石头数为i的情况可以由偶数张卡片组成
最后判断只能由奇数张卡片组成的石子数
奇数张卡片时先手必胜,偶数张先手必败
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> using namespace std; #define maxn 1e6+7 int a[10005],dp[100005][2]; int n,m; int main() { while(scanf("%d%d",&n,&m)!=EOF&&(n+m)) { memset(dp,false,sizeof(dp)); for(int i=0;i<n;i++) { scanf("%d",&a[i]); } for(int i=0;i<n;i++) { for(int j=m;j>=a[i];j--) { if(dp[j-a[i]][0]) dp[j][1]=true; if(dp[j-a[i]][1]) dp[j][0]=true; } dp[a[i]][1]=true; } int ans=0; for(int i=1;i<=m;i++) { if(dp[i][1]&&!dp[i][0]) ans++; } cout<<ans<<endl; } return 0; }