题面
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 ",dfs(0)); }