本题在洛谷上的链接:https://www.luogu.org/problemnew/show/P1006#sub
这道题和那道方格取数很像,都是多线程DP,模拟两条路走。具体实现看代码,但这种多线程的题有几个点需要注意:
1、dp数组的维度要够,因为是模拟多条路线。
2、多条路线交叉,交叉点只取一次。
3、路线必须起点相同,终点相同,不能正反颠倒,因为每个点只会取一次,假如起点终点不同,结果必受影响。
4、过程中路线会交叉,但最终答案路线是不会交叉的,因为如果两条路线交叉,必然存在两条不交叉且答案更大的路线。
1 #include<cstdio> 2 inline int max(int a,int b) {return a>b?a:b;} 3 const int mmax=55; 4 int n,m,map[mmax][mmax],dp[mmax][mmax][mmax][mmax]; 5 int main() { 6 scanf("%d%d",&n,&m); 7 for(int i=1;i<=n;++i) 8 for(int j=1;j<=m;++j) scanf("%d",&map[i][j]); 9 for(int i=1;i<=n;++i) 10 for(int j=1;j<=m;++j) 11 for(int k=1;k<=n;++k) 12 for(int l=1;l<=m;++l) { 13 dp[i][j][k][l]=max(dp[i-1][j][k-1][l],max(dp[i-1][j][k][l-1],max(dp[i][j-1][k-1][l],dp[i][j-1][k][l-1])))+map[i][j]; 14 if(!(i==k&&j==l)) dp[i][j][k][l]+=map[k][l]; 15 } 16 printf("%d",dp[n][m][n][m]); 17 return 0; 18 }