hlg2144两只猴子【dp】
两只猴子 | ||||||
|
||||||
Description | ||||||
两只猴子被猴王派去摘水果。 当这两只猴子到果园时,发现混世魔王带着一群妖怪杀了过来。于是,两只猴子打算分开行动,这样既可以逃走,又可以多采水果。 把果园看成n*m矩形,一只猴子从(1,1)出发,它只能向下或向右走;另一只从(n,1)出发,它只能向上或向右走。 由于妖怪们都很严格的执行混世魔王的命令,当它被派去追一只猴子时它不会去追另一只猴子。汗! 它们最多可以带多少水果会去呢? 注:它们有一种可以储存很多东西的法宝。它们走过的地方水果都会被采走。 |
||||||
Input | ||||||
第一行:整数n ,m (3<=n,m<=500) 接下来 输入n行 每行m个整数a[i][j] 表示水果的量(0<=a[i][j]<=10) |
||||||
Output | ||||||
最多可带多少水果。 |
||||||
Sample Input | ||||||
3 3 100 100 100 100 1 100 100 100 100 4 3 1 3 1 1 1 1 1 3 3 2 3 4 3 4 1 2 2 2 2 2 3 2 1 1 1 1 |
||||||
Sample Output | ||||||
801 23 19
|
这个题描述有问题……
这个题原意是给你一个矩阵从左上角到右下角一只猴子走 从左下角到右上角一只猴子走 问能带走多上
一次枚举每个点作为焦点然后dp来求就可以了
代码:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 6 #define sc scanf 7 #define pr printf 8 #define re return 9 #define me(a, b) memset(a, b, sizeof(a)); 10 #define fr(i, j, k) for(int i = j; i <= k; i++) 11 12 const int maxn = 505; 13 14 int a[maxn][maxn]; 15 int dp[5][maxn][maxn]; 16 17 int main() { 18 int n, m; 19 while(EOF != sc("%d %d",&n, &m) ) { 20 fr(i, 1, n) { 21 fr(j, 1, m) { 22 sc("%d",&a[i][j]); 23 } 24 } 25 me(dp, 0); 26 dp[1][1][1] = a[1][1]; 27 fr(i, 1, n) { 28 fr(j, 1, m) { 29 if(i == 1 && j == 1) continue; 30 if(i == 1) { 31 dp[1][i][j] = dp[1][i][j - 1] + a[i][j]; 32 continue; 33 } 34 if(j == 1) { 35 dp[1][i][j] = dp[1][i - 1][j] + a[i][j]; 36 continue; 37 } 38 dp[1][i][j] = max(dp[1][i][j], dp[1][i - 1][j] + a[i][j]); 39 dp[1][i][j] = max(dp[1][i][j], dp[1][i][j - 1] + a[i][j]); 40 } 41 } 42 43 dp[2][n][1] = a[n][1]; 44 for(int i = n; i >= 1; i--) { 45 for(int j = 1;j <= m; j++) { 46 if(i == n && j == 1) continue; 47 if(i == n) { 48 dp[2][i][j] = dp[2][i][j - 1] + a[i][j]; 49 continue; 50 } 51 if(j == 1) { 52 dp[2][i][j] = dp[2][i + 1][j] + a[i][j]; 53 continue; 54 } 55 dp[2][i][j] = max(dp[2][i][j], dp[2][i][j - 1] + a[i][j]); 56 dp[2][i][j] = max(dp[2][i][j], dp[2][i + 1][j] + a[i][j]); 57 58 } 59 } 60 61 dp[3][1][m] = a[1][m]; 62 fr(i, 1, n) { 63 for(int j = m; j >= 1; j--) { 64 if(i == 1 && j == m) continue; 65 if(i == 1) { 66 dp[3][i][j] = dp[3][i][j + 1] + a[i][j]; 67 continue; 68 } 69 if(j == m) { 70 dp[3][i][j] = dp[3][i - 1][j] + a[i][j]; 71 continue; 72 } 73 dp[3][i][j] = max(dp[3][i][j], dp[3][i][j + 1] + a[i][j]); 74 dp[3][i][j] = max(dp[3][i][j], dp[3][i - 1][j] + a[i][j]); 75 76 } 77 } 78 79 dp[4][n][m] = a[n][m]; 80 for(int i = n; i >= 1; i--) { 81 for(int j = m; j >= 1; j--) { 82 if(i == n && j == m) continue; 83 if(i == n) { 84 dp[4][i][j] = dp[4][i][j + 1] + a[i][j]; 85 continue; 86 } 87 if(j == m) { 88 dp[4][i][j] = dp[4][i + 1][j] + a[i][j]; 89 continue; 90 } 91 dp[4][i][j] = max(dp[4][i][j], dp[4][i][j + 1] + a[i][j]); 92 dp[4][i][j] = max(dp[4][i][j], dp[4][i + 1][j] + a[i][j]); 93 94 } 95 } 96 int ans = 0; 97 for(int i = 2; i < n; i++) { 98 for(int j = 2; j < m; j++) { 99 ans = max(ans, dp[1][i][j - 1] + dp[2][i + 1][j] + dp[3][i -1][j] + dp[4][i][j + 1] + a[i][j]); 100 ans = max(ans, dp[2][i][j - 1] + dp[4][i + 1][j] + dp[1][i -1][j] + dp[3][i][j + 1] + a[i][j]); 101 } 102 } 103 pr("%d\n",ans); 104 } 105 return 0; 106 }