Ural 1087. The Time to Take Stones

来源:互联网 发布:如何开淘宝 编辑:程序博客网 时间:2024/05/22 16:48

Ural 1087


我们需要知道一些博弈论的小知识。

我们用win[i]来表示i的状态;

win[i]=1表示比胜态

win[i]=0表示必败态


那么win[i] = 0 当且仅当 其所有的子状态 win[j] = 1;

      win[i] = 1 当且仅当 至少有一个子状态 win[j]=0;


我们用类似dp的方法求出win[n]就解决了这个问题。


CODE:

#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#include<vector>#include<set>#include<queue>#include<map>#include<sstream>#include<iostream>using namespace std;#define FOR(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)#define DOR(i,a,b) for(int (i)=(a);(i)>=(b);(i)--)#define bug puts("Fuck");#define LL long long#define pb push_back#define mp make_pair#define nMax 10100#define eps 1e-8#define inf 0x7fffffffint win[nMax];int n,k;int b[nMax];int main(){#ifndef ONLINE_JUDGE//freopen("input.txt","r",stdin);//freopen("output.txt","w",stdout);#endif    while(~scanf("%d%d",&n,&k)){        FOR(i,1,k) scanf("%d",&b[i]);        FOR(i,0,n) win[i]=-1;        win[0]=1;        for(int i=0;i<=n;i++)if(win[i]==1){            for(int j=1;j<=k;j++){                if(win[i+b[j]]==-1) win[i+b[j]]=0;                else win[i+b[j]] |=0;            }        }else if(win[i]==0){            for(int j=1;j<=k;j++) {                win[i+b[j]]=1;            }        }        if(win[n]) printf("1\n");        else printf("2\n");    }return 0;}


原创粉丝点击