BZOJ传送门
洛谷传送门
解析:
我们发现当前可决策格子是有限的,实际上,总的状态数非常少,只有9e4种左右,所以我们可以用一个longlong来压一下每一列当前已经决策了多少个格子,然后用哈希表记忆化搜索一下就行了。
代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define re register
#define cs const
struct Map{
static cs int magic=3721303;
ll key[magic];
int val[magic];
Map(){memset(key,-1,sizeof key);}
cs int &operator[](cs ll &k)cs{
int h=k%magic;
while((~key[h])&&(key[h]^k))h=(h+1)%magic;
return val[h];
}
int &operator[](cs ll &k){
int h=k%magic;
while((~key[h])&&(key[h]^k))h=(h+1)%magic;
if(key[h]^k)key[h]=k;
return val[h];
}
bool find(cs ll &k){
int h=k%magic;
while((~key[h])&&(key[h]^k))h=(h+1)%magic;
return key[h]==k;
}
}ma;
cs int INF=0x3f3f3f3f;
int a[11][11],b[11][11];
int n,m;
ll mask_one=15;
inline int get_state(ll sta,int pos){
return (sta&(mask_one<<(pos<<2)))>>(pos<<2);
}
inline ll set_state(ll sta,int pos,ll j){
return (sta&~(mask_one<<(pos<<2)))|(j<<(pos<<2));
}
inline int dfs(ll sta,bool who){
if(ma.find(sta))return ma[sta];
int res=who?-INF:INF;
for(int re i=1;i<=m;++i){
int pre=get_state(sta,i-1),now=get_state(sta,i);
if((i==1||now<pre)&&now<n){
res=who?
max(res,dfs(set_state(sta,i,now+1),who^1)+a[now+1][i]):
min(res,dfs(set_state(sta,i,now+1),who^1)-b[now+1][i]);
}
}
return ma[sta]=res;
}
signed main(){
scanf("%d%d",&n,&m);
for(int re i=1;i<=n;++i)for(int re j=1;j<=m;++j)scanf("%d",&a[i][j]);
for(int re i=1;i<=n;++i)for(int re j=1;j<=m;++j)scanf("%d",&b[i][j]);
ll s=0;for(int re i=1;i<=m;++i)s=set_state(s,i,n);
ma[s]=0;
cout<<dfs(0,1);
return 0;
}