博弈论合集
2016-07-24 22:17
281 查看
hdu 1847
hdu 1848
hdu 5724
hdu 1809
这道题目我一定要好好吐槽一下,二维char数组表示成一维string,用来表示状态,然后求sg函数值用记忆化搜索,然后就一直WA,心好累差点怀疑人生,QAQ。后来发现记忆化搜索代码加上 if(vis[str])return sg[str]; 就WA,所以肯定这里出问题,后来一想,这种状态表示有毒,例如5x4与4x5的矩阵显然不同,但是展开成一维string时显然可以得到相同string,所以二维展一维时除了内容,还要加上R,C两个参数。可是这样就要用结构体,想想acm中处理字符串的技巧,其实在二维数组表示成string时,在末尾加上一个区别的符号就行了。这样就可以写最正宗的记忆化搜索了。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <map>
#include <cstring>
using namespace std;
char g[55][55];
map<string,int>sg;
map<string,int>vis;
string ss;
int R,C;
string tostr(){
ss="";
for(int i=0;i<R;i++){
ss+=g[i];
ss+='*';
}
return ss;
}
int grundy(){
string str=tostr();//cout<<str<<endl;
if(vis[str])return sg[str];
int s[100];
memset(s,0,sizeof(s));
for(int i=1;i<R;i++){
for(int j=1;j<C;j++){
if(g[i][j]=='0'&&g[i-1][j]=='0'&&g[i][j-1]=='0'&&g[i-1][j-1]=='0'){
g[i][j]='1';g[i-1][j]='1';g[i][j-1]='1';g[i-1][j-1]='1';
s[grundy()]=1;
g[i][j]='0';g[i-1][j]='0';g[i][j-1]='0';g[i-1][j-1]='0';
}
}
}
int k=0;
while(s[k])k++;
vis[str]=1;
sg[str]=k;
return k;
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF){
int ans=0;
for(int i=0;i<n;i++){
scanf("%d%d",&R,&C);
for(int j=0;j<R;j++)scanf("%s",g[j]);
ans^=grundy();
}
printf("%s\n",ans?"Yes":"No");
}
return 0;
}
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> using namespace std; int dp[1003]; int main() { int p[30]; p[0]=1; for(int i=1;i<20;i++){ p[i]=p[i-1]<<1; } memset(dp,0,sizeof(dp)); dp[0]=0;dp[1]=1; dp[2]=1; for(int i=3;i<1003;i++){ for(int j=0;j<20;j++){ if(p[j]<=i){ if(dp[i-p[j]]==0)dp[i]=1; } } } int n; while(scanf("%d",&n)!=EOF){ dp ==0?printf("Cici\n"):printf("Kiki\n"); } return 0; }
hdu 1848
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <set> using namespace std; int sg[1045]; int f[100]; void grundy(){ sg[0]=0; for(int j=1;j<=1000;j++){ set<int >s; for(int i=1;i<20;i++){ if(f[i]<=j)s.insert(sg[j-f[i]]); } int g=0; while(s.count(g))g++; sg[j]=g; } } int main() { f[0]=1; f[1]=1; f[2]=2; for(int i=3;i<20;i++){ f[i]=f[i-1]+f[i-2]; } grundy(); int n,m,p; while(~scanf("%d%d%d",&n,&m,&p)){ if(!n&&!m&&!p)break; string ans=(sg ^sg[m]^sg[p])==0?"Nacci":"Fibo"; cout<<ans<<endl; } return 0; }
hdu 5724
#include <iostream> #include <cstdlib> #include <cstdio> #include <algorithm> #include <set> #include <cstring> using namespace std; int sg[1100000]; int s[30]; void grundy(){ sg[0]=0; for(int i=1;i<(1<<20);i++){ memset(s,0,sizeof(s)); for(int j=0;j<20;j++){ if(i&(1<<j)){ for(int k=j;k>=0;k--){ if(!(i&(1<<k))){ s[sg[( (i^(1<<j) )|(1<<k))]]=1; break; } } } } for(int j=0;j<30;j++){ if(s[j]==0){ sg[i]=j;break; } } } } int main() { grundy(); int t; scanf("%d",&t); while(t--){ int n; scanf("%d",&n); int ans=0; for(int i=0;i<n;i++){ int m; scanf("%d",&m); int tmp=0; for(int j=0;j<m;j++){ int z; scanf("%d",&z); tmp|=1<<(20-z); } ans^=sg[tmp]; } if(ans)printf("YES\n"); else printf("NO\n"); } return 0; }
hdu 1809
这道题目我一定要好好吐槽一下,二维char数组表示成一维string,用来表示状态,然后求sg函数值用记忆化搜索,然后就一直WA,心好累差点怀疑人生,QAQ。后来发现记忆化搜索代码加上 if(vis[str])return sg[str]; 就WA,所以肯定这里出问题,后来一想,这种状态表示有毒,例如5x4与4x5的矩阵显然不同,但是展开成一维string时显然可以得到相同string,所以二维展一维时除了内容,还要加上R,C两个参数。可是这样就要用结构体,想想acm中处理字符串的技巧,其实在二维数组表示成string时,在末尾加上一个区别的符号就行了。这样就可以写最正宗的记忆化搜索了。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <map>
#include <cstring>
using namespace std;
char g[55][55];
map<string,int>sg;
map<string,int>vis;
string ss;
int R,C;
string tostr(){
ss="";
for(int i=0;i<R;i++){
ss+=g[i];
ss+='*';
}
return ss;
}
int grundy(){
string str=tostr();//cout<<str<<endl;
if(vis[str])return sg[str];
int s[100];
memset(s,0,sizeof(s));
for(int i=1;i<R;i++){
for(int j=1;j<C;j++){
if(g[i][j]=='0'&&g[i-1][j]=='0'&&g[i][j-1]=='0'&&g[i-1][j-1]=='0'){
g[i][j]='1';g[i-1][j]='1';g[i][j-1]='1';g[i-1][j-1]='1';
s[grundy()]=1;
g[i][j]='0';g[i-1][j]='0';g[i][j-1]='0';g[i-1][j-1]='0';
}
}
}
int k=0;
while(s[k])k++;
vis[str]=1;
sg[str]=k;
return k;
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF){
int ans=0;
for(int i=0;i<n;i++){
scanf("%d%d",&R,&C);
for(int j=0;j<R;j++)scanf("%s",g[j]);
ans^=grundy();
}
printf("%s\n",ans?"Yes":"No");
}
return 0;
}
相关文章推荐
- [FAFU 1292]博弈论,组合游戏,取石游戏
- Sicily 1305 Who’s Winner?
- 三种类型博弈(bash + nimm +wythoff)
- Andrew Stankevich Contest 38 , J-Jackpot
- 纸牌博弈问题
- HDU1527 纯威左夫博弈
- uva 12293 Box Game
- hdu 1846 (博弈)
- HDU 1849(尼姆博弈)
- hdu 1847(博弈)
- hdu 1850(妮姆博奕)
- HDU 1079 Calendar Game
- cf 276b 博弈
- Hdu2177-博弈(Sg函数找规律)
- SG-分石子游戏
- 博弈-取石子
- 博弈-威佐夫博弈
- 博弈-巴什博弈
- 博弈-Nim博弈
- 取石子游戏 (HDU_256) 斐波拉契 博弈