【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 }