简单记忆化搜索.
显然,数字的形态是类似阶梯下降的,状态数不会太多,记忆化爆搜就行.
code:
#include <bits/stdc++.h>
#define N 12
#define mod 1000000007
#define base 12
#define ll long long
#define inf 1000000000
#define setIO(s) freopen(s".in","r",stdin)
using namespace std;
map<ll,int>vis;
map<ll,int>fin;
int n,m;
int cur[12],A[12][12],B[12][12];
ll ha()
{
ll an=1;
for(int i=1;i<=n;++i)
{
if(!cur[i])
break;
an=an*base+cur[i];
}
return an;
}
// 非 - 黑 - A
// 牛 - 白 - B
// d=1:非走;d=0 : 牛走
// d=1: f[now]=max(f[now],a[选]+f[now+a]);
// d=0: f[now]=min(f[now],-b[选]+f[now+a]);
int solve(int d)
{
ll cu=ha();
if(vis[cu])
return fin[cu];
vis[cu]=1;
int tmp=(d==1?-inf:inf);
for(int i=1;i<=n;++i)
{
if(cur[i]<cur[i-1])
{
++cur[i];
if(d==1)
tmp=max(tmp,A[i][cur[i]]+solve(d^1));
else
tmp=min(tmp,-B[i][cur[i]]+solve(d^1));
--cur[i];
}
}
fin[cu]=tmp;
return tmp;
}
int main()
{
// setIO("input");
int i,j;
scanf("%d%d",&n,&m);
for(i=1;i<=n;++i)
for(j=1;j<=m;++j)
scanf("%d",&A[i][j]);
for(i=1;i<=n;++i)
for(j=1;j<=m;++j)
scanf("%d",&B[i][j]);
cur[0]=m;
for(i=1;i<=n;++i)
cur[i]=m;
ll c=ha();
vis[c]=1;
fin[c]=0;
for(i=1;i<=n;++i)
cur[i]=0;
printf("%d\n",solve(1));
return 0;
}