bzoj5248: [2018多省省队联测]一双木棋
题目链接
题解
现场居然没写出来.....真是脑残限制想象力
棋子的摆放形态是递增的,状态数并不多,三十多万吧
对抗搜索,map记忆化一下状态。完了
当时没敢想.....唉
hash的时候卡了以下base.....10 or 11以下会T,好玄学啊
代码
#include<map>
#include<cstdio>
#include<cstring>
#include<algorithm>
const int maxn = 13;
#define LL long long
int n,m;
int a[maxn][maxn],b[maxn][maxn];
int sta[maxn];
int base = 13;
std::map<LL,int>mp;
inline LL hash() {
LL ret = 0;
for(int i = 1;i <= n;++ i) ret = ret * base + sta[i];
return ret;
}
void get_s(LL tmp) {
for(int i = n;i;i --) sta[i] = tmp % base,tmp /= base;
//puts("") ;
}
inline bool get_NS () {
int ret = 0;
for(int i = 1;i <= n;++ i) ret += sta[i];
return ret & 1;
}
inline int dfs(LL state) {
if(mp.find(state) != mp.end()) return mp[state];
get_s(state);
bool type = get_NS() ;
int ret = type ? 0x3f3f3f3f : -0x3f3f3f3f;
for(int i = 1;i <= n;++ i)
if(sta[i - 1] > sta[i]) {
++ sta[i];
LL Next = hash();
if(!type) ret = std::max(ret,dfs(Next) + a[i][sta[i]]);
else ret = std::min(ret,dfs(Next) - b[i][sta[i]]);
-- sta[i];
}
mp[state] = ret;
//printf("%d\n",ret);
return ret;
}
int main() {
scanf("%d%d",&n,&m);
for(int i = 1;i <= n;++ i)
for(int j = 1;j <= m;++ j)
scanf("%d",&a[i][j]);
for(int i = 1;i <= n;++ i)
for(int j = 1;j <= m;++ j)
scanf("%d",&b[i][j]);
sta[0] = m;
for(int i = 1;i <= n;++ i) sta[i] = m;
mp[hash()] = 0;
dfs(0);
//for(int i = 1;i <= 10000*n;++ i) {
//printf("%d\n",mp[i]);
//}
printf("%d\n",mp[0]);
return 0;
}