$n \leq 200,m \leq 200$,$n*m$的矩阵,从左上到右下走一次只能向右向下,从右下到左上走一次只能向左向上,把两条路取并集,覆盖的数字加起来(经过两次的数算一次),问最大值多少。
费用流。或dp。dp的四维里面,有三维可以定剩下一维(步数一定),因此去掉一维即可。
1 //#include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 //#include<math.h> 5 //#include<set> 6 //#include<queue> 7 //#include<vector> 8 #include<algorithm> 9 #include<stdlib.h> 10 using namespace std; 11 12 #define LL long long 13 int qread() 14 { 15 char c; int s=0,f=1; while ((c=getchar())<'0' || c>'9') (c=='-') && (f=-1); 16 do s=s*10+c-'0'; while ((c=getchar())>='0' && c<='9'); return s*f; 17 } 18 19 //Pay attention to '-' , LL and double of qread!!!! 20 21 int m,n; 22 #define maxn 233 23 int f[2][maxn][maxn],cur=0,a[maxn][maxn]; 24 int main() 25 { 26 m=qread(); n=qread(); 27 for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) a[i][j]=qread(); 28 for (int i=1;i<=n;i++) 29 for (int j=1;j<=n;j++) 30 f[0][i][j]=-0x3f3f3f3f; 31 f[0][1][1]=a[1][1]; 32 for (int i=1,to=n+m-3;i<=to;i++) 33 { 34 for (int j=1;j<=n;j++) 35 for (int k=1;k<=n;k++) 36 f[cur^1][j][k]=-0x3f3f3f3f; 37 for (int j=max(1,i+2-m),too=min(i+1,n);j<=too;j++) 38 for (int k=max(1,i+2-m),tooo=min(i+1,j-1);k<=tooo;k++) if (j!=k) 39 { 40 f[cur^1][j][k]=max(f[cur^1][j][k],f[cur][j-1][k-1]); 41 f[cur^1][j][k]=max(f[cur^1][j][k],f[cur][j][k-1]); 42 f[cur^1][j][k]=max(f[cur^1][j][k],f[cur][j-1][k]); 43 f[cur^1][j][k]=max(f[cur^1][j][k],f[cur][j][k]); 44 f[cur^1][j][k]+=a[j][i-j+2]+a[k][i-k+2]; 45 } 46 cur^=1; 47 } 48 printf("%d\n",f[cur][n][n-1]+a[n][m]); 49 return 0; 50 }