题目连接:
我想了很久都没有想到怎么递推,看了题解后试着自己写,结果第二组数据就 wa 了,后来才知道自己没有判选择的两条路径是否只是一个交点。
大概思路是:先预处理出每个格子到四个角落格子的路径最大数值,然后枚举两个人相遇的交点格子,枚举 A、B 的进来和出去方式(记两个线路为 1 和 2,考虑一个公共点,1 为左进右出,2 为下进上出;1 上进下出,2 为左进右出),然后求最大值即可。
注意边界情况。
原题解链接:,
我的代码:(全用宏定义了 -_-|| )
1 #include2 #include 3 #include 4 using namespace std; 5 #define sd(x) scanf("%d",&(x)) 6 #define sd2(x,y) scanf("%d %d",&(x),&(y)) 7 typedef long long LL; 8 9 LL dp[5][1003][1003], a[1003][1003];10 11 #define For(i,s,t) for(int i = s; i <= t; ++i)12 #define desFor(i,t,s) for(int i = t; i >= s; --i)13 14 int main() {15 int n,m;16 while(~sd2(n,m)) {17 For(k,1,4) For(i,0,n+1)18 dp[k][i][m + 1] = 0;19 For(k,1,4) For(j,0,m+1)20 dp[k][n + 1][j] = 0;21 For(i,1,n) For(j,1,m)22 sd(a[i][j]);23 // 递推预处理出所有交点到 4 个角的最大值24 For(i,1,n) For(j,1,m)25 dp[1][i][j] = max(dp[1][i-1][j], dp[1][i][j-1]) + a[i][j];26 For(i,1,n) desFor(j,m,1)27 dp[2][i][j] = max(dp[2][i-1][j], dp[2][i][j+1]) + a[i][j];28 desFor(i,n,1) For(j,1,m)29 dp[3][i][j] = max(dp[3][i+1][j], dp[3][i][j-1]) + a[i][j];30 desFor(i,n,1) desFor(j,m,1)31 dp[4][i][j] = max(dp[4][i+1][j], dp[4][i][j+1]) + a[i][j];32 LL ans = 0;33 // 枚举所有交点34 For(i,2,n-1) For(j,2,m-1) {35 // 第一种路径选择: A 从上往下穿过交点 dp[i][j],B 从左向右穿过 dp[i][j]36 LL first = dp[1][i-1][j] + dp[4][i+1][j] + dp[2][i][j+1] + dp[3][i][j-1];37 ans = max(ans, first);38 // 第二种路径选择: A 从左向右穿过交点 dp[i][j],B 从上往下穿过 dp[i][j]39 LL second = dp[1][i][j-1] + dp[4][i][j+1] + dp[2][i-1][j] + dp[3][i+1][j];40 ans = max(ans, second);41 }42 printf("%I64d\n",ans);43 }44 return 0;45 }