终于有一道一遍过的题了/kk/kk
发现前几道都很难(总之暂时没想出来)就先把这个写了。
其实这题四维 dp 好像能过,但既然写了就写正解吧...
因为路径正着走和反着走都是一样的,所以问题就是求从左上走到右下两条不重合的最大路径。
在转移途中,因为两个路径的长度都一样,所以枚举横纵坐标的和作为第一维(i),两条路径的横坐标(j,k)作为第2,3维。
然后就可以求出横纵坐标了。
注意 j 要始终小于 k ,不然路径会重合(只要它们横坐标不等,就一定不会经过同一个点,路径也就一定不会重合)。
#include<bits/stdc++.h> using namespace std; int m,n,a[51][51],f[101][51][51]; //第一维的数组要开两倍qaq int main() { scanf("%d%d",&m,&n); for(int i=1;i<=m;i++) { for(int j=1;j<=n;j++) { scanf("%d",&a[i][j]); } } for(int i=3;i<=m+n;i++) { for(int j=1;j<=m && j<=i;j++) { for(int k=j+1;k<=m && k<=i;k++) { f[i][j][k]=max(f[i-1][j-1][k],max(f[i-1][j][k],max(f[i-1][j][k-1],f[i-1][j-1][k-1])))+a[j][i-j]+a[k][i-k]; } } } printf("%d",f[m+n-1][m-1][m]);//因为无论如何都到不了f[m+n][m][m],所以直接把上一步答案输出来就好了。 return 0; }