题面
https://www.luogu.org/problem/P4363
题解
很套路的$hash$状态$+dp$。
可知棋子形成的形状一定是一个连续的倒楼梯形(楼梯向右延伸的长度可以不连续,但一定单调)
$hash$轮廓就行了。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#define ri register int
#define N 11
#define LL long long
#define INF 1000000007
#define mod 1233107
using namespace std;
int a[N][N],b[N][N];
LL pow[N];
int n,m;
vector<int>f[mod];
vector<LL>g[mod];
int dfs(LL x) {
int ln[N];
int yx=x%mod;
for (ri i=0;i<g[yx].size();i++) if (g[yx][i]==x) return f[yx][i];
g[yx].push_back(x);
f[yx].push_back(0);
int tl=f[yx].size()-1;
int tot=0,opt,ret;
LL tx=x,nx;
for (ri i=n;i>=1;i--) {
ln[i]=x/pow[i];
x%=pow[i];
}
ln[0]=m+1;
for (ri i=1;i<=n;i++) tot+=ln[i];
if (tot==n*m) return 0;
if (tot%2==0) opt=1; else opt=0;
if (opt) ret=-INF; else ret=INF;
for (ri i=1;i<=n;i++) if (ln[i-1]>ln[i] && ln[i]+1<=m) {
nx=tx+pow[i];
if (opt) {
int t=dfs(nx);
if (a[i][ln[i]+1]+t>ret) ret=a[i][ln[i]+1]+t;
}
else {
int t=dfs(nx);
if (-b[i][ln[i]+1]+t<ret) ret=-b[i][ln[i]+1]+t;
}
}
return f[yx][tl]=ret;
}
int main(){
cin>>n>>m;
for (ri i=1;i<=n;i++)
for (ri j=1;j<=m;j++) cin>>a[i][j];
for (ri i=1;i<=n;i++)
for (ri j=1;j<=m;j++) cin>>b[i][j];
pow[1]=1LL;
for (ri i=2;i<=n;i++) pow[i]=pow[i-1]*11LL;
printf("%d\n",dfs(0));
}