版权声明:虽然博主很菜,但是还是请注明出处(我觉得应该没人偷我的博客) https://blog.csdn.net/qq_43346903/article/details/87925907
典型的
搜索,状态有点多,需要记忆化
搜索的状态都是一个阶梯形的,可以
压起来
搜索,也称对抗搜索,常见于博弈类问题,即最后得分为
想让
极大,
想让
极小,那么只需要看看搜索到当前状态该谁下就可以判断取
还是取
Code:
#include<bits/stdc++.h>
#define INF 1000000000
#define ll long long
using namespace std;
inline int read(){
int res=0,f=1;char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-f;ch=getchar();}
while(isdigit(ch)) {res=(res<<1)+(res<<3)+(ch^48);ch=getchar();}
return res*f;
}
const int N=15;
ll lim;
int n,m;
int a[N][N],b[N][N];
int pt[N];
map<ll,int>mp;
inline ll hash(){
ll res=0;
for(int i=1;i<=n;i++) res=res*11+pt[i];
return res;
}
inline int unzip(ll now){
int res=0;
for(int i=n;i;i--) pt[i]=now%11,now/=11;
for(int i=1;i<=n;i++) res+=pt[i];
return res&1;
}
int dfs(ll now){
if(mp.count(now)) return mp[now];
int per=unzip(now),res=per?INF:-INF;
for(int i=1;i<=n;i++)
if(pt[i-1]>pt[i]){
pt[i]++;
ll hs=hash();
per?res=min(res,dfs(hs)-b[i][pt[i]]):res=max(res,dfs(hs)+a[i][pt[i]]);
pt[i]--;
}
mp[now]=res;
return res;
}
int main(){
n=read();pt[0]=m=read();
for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) a[i][j]=read();
for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) b[i][j]=read();
for(int i=1;i<=n;i++) lim=lim*11+m;
mp[lim]=0;
dfs(0);
cout<<mp[0];
return 0;
}