题目链接:https://acm.zzuli.edu.cn/zzuliacm/problem.php?id=1875
基本思想:dp
题目很容易看得出来是动态规划,但是太渣不知道该如何dp,看了一些博客才明白还可以这种“双路dp”
dp[k][i][j]:=两个人都走了k步(其实两个人走的步数一样应该),A在第i行,B在第j行
然后有四种状态dp[k-1][i][j], dp[k-1][i-1][j] ,dp[k-1][i][j-1] ,dp[k-1][i-1][j-1],状态转移的时候选择最大值即可
注意最后要输出的是dp[n+m-2][n][n](数组下标从1开始)
代码:
1 #define _CRT_SECURE_NO_WARNINGS 2 #include<cstdio> 3 #include<iostream> 4 #include<algorithm> 5 #include<string.h> 6 using namespace std; 7 8 const int MAX_N = 105; 9 10 int a[MAX_N][MAX_N]; 11 int dp[2 * MAX_N][2 * MAX_N][2 * MAX_N]; 12 13 int main() { 14 int t; 15 ios::sync_with_stdio(true); 16 cin >> t; 17 while (t--) { 18 memset(a, 0, sizeof(a)); 19 memset(dp, 0, sizeof(dp)); 20 int n, m; 21 cin >> n >> m; 22 for (int i = 1; i <= n; i++) { 23 for (int j = 1; j <= m; j++) { 24 cin >> a[i][j]; 25 } 26 } 27 dp[0][1][1] = a[1][1]; 28 29 for (int k = 1; k <= n + m - 2; k++) { 30 for (int i = 1; i <= n; i++) { 31 for (int j = 1; j <=n; j++) { 32 dp[k][i][j] = max(max(dp[k - 1][i][j - 1], dp[k - 1][i - 1][j]), 33 max(dp[k - 1][i - 1][j - 1], dp[k - 1][i][j])); 34 dp[k][i][j] += a[i][k - i + 2] + a[j][k - j + 2]; 35 dp[k][i][j] -= (i == j ? a[j][k - j + 2] : 0); 36 } 37 } 38 } 39 printf("%d ", dp[n + m - 2][n][n]); 40 } 41 return 0; 42 }