题解:P7656 [BalticOI 1996] A NUMBER GAME (Day 2)
题意
最开始有两个数
给出
题解
尊重随机跳题。
看到数据范围 int 就能存下。
在本题中,我们认为 x>>i&1 判断,这里的第
对于某一个状态
不难想到记忆化搜索。枚举下一步选的数是
判断能不能赢的事情解决了,但题目还要问怎么选取
代码:
#include<iostream>
using namespace std;
int n,m;
int mem[1<<21|1];//=0表示失败;非零数字表示需要选择mem[x]就会必赢
bool vis[1<<21|1];
int dfs(int x){
if(vis[x]) return mem[x];
int curn=n;
for(int i=1;i<=m;i++){
if(x>>i&1){
curn-=i;
}
}
for(int i=min(curn,m);i>=1;i--){
if(x>>i&1) continue;
int res=dfs(x|(1<<i));
if(res==0){
vis[x]=true;
return mem[x]=i;
}
}
vis[x]=true;
return mem[x]=0;
}
int main(){
cin >> n >> m;
if(dfs(0)){
cout << " A wins\n";
} else{
cout << " B wins\n";
}
for(int i=1;i<=m && i<=n;i++){
if(i<=9) cout << " ";
cout << i << " ";
int res=dfs(1<<i);
if(res==0){
cout << "winning" << "\n";
} else{
cout << res << "\n";
}
}
return 0;
}
备注
这题的输出格式要求输出的前十行都有空格,所以代码会有奇怪的判断和空格。来源。