【NOIP2008】传纸条

本题在洛谷上的链接:https://www.luogu.org/problemnew/show/P1006#sub


这道题和那道方格取数很像,都是多线程DP,模拟两条路走。具体实现看代码,但这种多线程的题有几个点需要注意:

1、dp数组的维度要够,因为是模拟多条路线。

2、多条路线交叉,交叉点只取一次。

3、路线必须起点相同,终点相同,不能正反颠倒,因为每个点只会取一次,假如起点终点不同,结果必受影响。

4、过程中路线会交叉,但最终答案路线是不会交叉的,因为如果两条路线交叉,必然存在两条不交叉且答案更大的路线。

 1 #include <cstdio>
 2 #include <algorithm>
 3 
 4 using namespace std;
 5 
 6 const int mmax = 55;
 7 
 8 int mt[mmax][mmax], dp[mmax][mmax][mmax][mmax];
 9 
10 int main() {
11     int m, n;
12     scanf("%d%d", &m, &n);
13     for (int i = 1; i <= m; ++i)
14         for (int j = 1; j <= n; ++j)
15             scanf("%d", &mt[i][j]);
16     for (int i = 1; i <= m; ++i)
17         for (int j = 1; j <= n; ++j)
18             for (int k = 1; k <= m; ++k)
19                 for (int l = 1; l <= n; ++l) {
20                     dp[i][j][k][l] = max(dp[i - 1][j][k - 1][l], dp[i - 1][j][k][l - 1]);
21                     dp[i][j][k][l] = max(dp[i][j][k][l], dp[i][j - 1][k - 1][l]);
22                     dp[i][j][k][l] = max(dp[i][j][k][l], dp[i][j - 1][k][l - 1]);
23                     if (!(i == k && j == l)) dp[i][j][k][l] += mt[i][j] + mt[k][l];
24                     else dp[i][j][k][l] += mt[i][j];
25                 }
26     printf("%d", dp[m][n][m][n]);
27     return 0;
28 }
AC代码
原文地址:https://www.cnblogs.com/Mr94Kevin/p/9613307.html