[BZOJ5428][九省联考2018]双木棋
去年觉得高不可攀的题啊...
貌似就很沙茶了QAQ
直接状压每一行是多少然后合法状态是LIS状态数极少所以随便dp一下就好了啊...
注意初值啥的得赋对才行QAQ
我菜死了
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
//Love and Freedom. #include<cstdio> #include<cmath> #include<algorithm> #include<cstring> #include<map> #define ll long long #define inf 2002122500 using namespace std; int a[11][11],b[11][11],n,m; map<ll,int> f[2]; map<ll,bool> vis[2]; ll mm[11]; int dp(ll w,int hd) { if(vis[hd][w]) return f[hd][w]; vis[hd][w]=1; ll rem=w; int ans=(hd==0?-inf:inf); int tmp=m,nt=0; bool qaq=0; for(int i=1;i<=n;i++) { nt=w%(m+1); w/=(m+1); if(tmp>=nt+1) { qaq=1; if(hd==0) ans=max(ans,a[i][nt+1]+dp(rem+mm[i],hd^1)); else ans=min(ans,dp(rem+mm[i],hd^1)-b[i][nt+1]); } tmp=nt; } if(!qaq) return 0; return f[hd][rem]=ans; } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) scanf("%d",&a[i][j]); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) scanf("%d",&b[i][j]); mm[1]=1; for(int i=2;i<=n;i++) mm[i]=mm[i-1]*(m+1); printf("%d\n",dp(0,0)); return 0; }