http://codeforces.com/problemset/problem/762/D
因为是3*n很巧妙的地方是 往左走两步或更多的走法都可以用往回走以一步
并走完一列来替换 那么走的方法就大大减少 左边一列转移到右边一列 每个
格子的转移方法枚举出来 用动态规划即可解决
最主要的是因为他能够往回走.
但是我们画图可以发现:每次往回走一定不用超过1次.
也就是说,最多只能走成这样
而不会走成这样
因为下图的走法一定可以用上图组合,并且
由于只用3行的特性,每次向回走实际上是取走了所有的数.
所以我们只采用上图方式得出来的答案一定最优
1 #include <bits/stdc++.h> 2 #define INF 0x7fffffff 3 using namespace std; 4 5 typedef long long LL; 6 LL grid[3][100007]; 7 LL tmp[3][100007]; 8 LL dp[3][100007]; 9 int main() 10 { 11 int n; 12 scanf("%d", &n); 13 for (int i = 0; i < 3; i++) 14 for (int j = 0; j < n; j++) 15 { 16 scanf("%lld", &grid[i][j]); 17 } 18 dp[0][0] = grid[0][0]; 19 dp[1][0] = grid[0][0] + grid[1][0]; 20 dp[2][0] = grid[0][0] + grid[1][0] + grid[2][0]; 21 tmp[0][0] = grid[0][0]; 22 tmp[1][0] = grid[1][0]; 23 tmp[2][0] = grid[2][0]; 24 for(int j = 1;j < n; j++) 25 { 26 for (int i = 0; i < 3; i++) 27 { 28 dp[i][j] = tmp[i][j] = dp[i][j-1] + grid[i][j]; 29 }//这样的转移走法 包括了所有的走法 30 dp[0][j] = max(dp[0][j], tmp[1][j] + grid[0][j]); 31 dp[0][j] = max(dp[0][j], tmp[2][j] + grid[1][j] + grid[0][j]); 32 dp[1][j] = max(dp[1][j], tmp[0][j] + grid[1][j]); 33 dp[1][j] = max(dp[1][j], tmp[2][j] + grid[1][j]); 34 dp[2][j] = max(dp[2][j], tmp[1][j] + grid[2][j]); 35 dp[2][j] = max(dp[2][j], tmp[0][j] + grid[1][j] + grid[2][j]); 36 dp[0][j] = max(dp[0][j], tmp[2][j-1] + grid[2][j] + grid[1][j] + grid[1][j-1] + grid[0][j-1] + grid[0][j]); 37 dp[2][j] = max(dp[2][j], tmp[0][j-1] + grid[0][j] + grid[1][j] + grid[1][j-1] + grid[2][j-1] + grid[2][j]); 38 } 39 cout << dp[2][n-1] << endl; 40 return 0; 41 }
dp[i][j] i 行 j 列可以得到的最大值
tmp[i][j]直接从右边一个走过来的得到的值