Cutting Game(Grundy值)
作者:互联网
就记住了一句话,对于分割问题,分割后各部分Grundy值异或后的值等于分割前的Grundy值
#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define pi acos(-1.0)
#define e exp(1.0)
const ll maxn=300;
ll w,h;
ll mem[maxn][maxn];//记录Grundy值
//用记忆化搜索计算Grundy值
ll Grundy(ll w,ll h)
{
if(mem[w][h]!=-1)
return mem[w][h];
set<int>s;
for(ll i=2;w-i>=2;i++)
s.insert(Grundy(i,h)^Grundy(w-i,h));
for(ll i=2;h-i>=2;i++)
s.insert(Grundy(w,i)^Grundy(w,h-i));
ll g=0;
while(s.count(g)!=0) g++;
return mem[w][h]=g;
}
int main()
{
// freopen(".../.txt","w",stdout);
ios::sync_with_stdio(false);
cin>>w>>h;
memset(mem,-1,sizeof(mem));
ll jie=Grundy(w,h);
if(jie)
puts("Win");
else
puts("Lose");
return 0;
}
我开始有个疑问:为什么求Grundy值的函数中两层for循环要保证被被分割后的图形的长宽一定要大于等于2呢?结合后面的代码我是这样理解的,那两层for循环是判断当前状态是否可能是必胜态,既然是判断必胜态,肯定是从有可能的状态进行判断,而一旦分割出了长或宽为1的情况,那就一定是必败态了,所以不能考虑这种情况,必须得从长宽大于等于2来判断。如果当前状态的Grundy值是0,那就是必败态,否则即为必胜态
嘘……一只bug 发布了50 篇原创文章 · 获赞 4 · 访问量 931 私信 关注标签:分割,return,mem,ll,++,Game,Cutting,Grundy 来源: https://blog.csdn.net/weixin_43311695/article/details/104582715