首页 > 代码库 > CodeForces 762D Maximum path

CodeForces 762D Maximum path

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]直接从右边一个走过来的得到的值

CodeForces 762D Maximum path