分析
我们用0表示向右,1表示向上
于是可以得到一条江棋盘分为两块的线
直接dp即可
代码
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> #include<cctype> #include<cmath> #include<cstdlib> #include<ctime> #include<queue> #include<vector> #include<set> #include<map> #include<stack> using namespace std; const int inf = 1e9+7; int n,m,dp[3001000],a[110][110],b[110][110],M; bool vis[3001000]; inline int work(int msk,int wh){ if(vis[msk])return dp[msk]; int res=wh?-inf:inf; vis[msk]=1; for(int i=0,j=n+1,k=1;i<n+m;i++){ if(!(msk&(1<<i)))k++; else j--; if(i==n+m-1||((msk>>i)&3)!=1)continue; if(wh)res=max(res,work(msk^(3<<i),wh^1)+a[j][k]); else res=min(res,work(msk^(3<<i),wh^1)-b[j][k]); } return dp[msk]=res; } int main(){ int i,j,k; 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]); M=(1<<(n+m))-1; vis[((1<<n)-1)<<m]=1; printf("%d",work((1<<n)-1,1)); return 0; }
原文地址:https://www.cnblogs.com/yzxverygood/p/10439157.html
时间: 2024-10-02 03:50:10