LightOJ 1004 Monkey Banana Problem
2017-11-08 16:12
274 查看
LightOJ 1004
题意:
题目给了一张地图,地图上的数字表示猴子走到这点后能够取得的香蕉数目,猴子只能从自己当前位置向下一行的相邻位置转移,求得到最多的香蕉的数量
这道题跟数字三角形是一个意思的,只是这道题的走的图形不是一个三角形而是菱形,菱形相当于一个正的三角形和一个倒着的三角形拼接而成的。
我们来看菱形的上部分,用dp[i][j]表示在i,j位置得到的最大的香蕉数量.
如果从上往下推:不难发现对于每个边缘的位置,只能从它的上一行的一个位置推下来,比如dp[2][1]位置,只能由dp[1][1]走下来,而dp[3][3]只能由dp[2][2]走下来,而除了dp[i][1]和dp[i][i]这样的边界位置,其余的位置都是由上一行的相邻两个位置推出的,这就涉及到了边界处理
转移方程为:
if(j == 1) dp[i][j] = dp[i - 1][j] + map[i][j];
if (j == i) dp[i][j] = dp[i - 1][j - 1] + map[i][j];
else dp[i][j] = max(dp[i - 1][j - 1], dp[i - 1][j]) + map[i][j];
如果倒着推:不难发现,对于每一个元素,都是由下一行的两个相邻位置转移过来的, 所以不存在边界处理,我想这就是为啥在做数字三角形的时候,大佬们选择倒推的原因吧。。。
转移方程为:
dp[i][j] = max(dp[i + 1][j], dp[i + 1][j + 1]) + map[i][j];
很不幸,这道题不管是正着推还是倒推,都会涉及边界处理,因为这有一个倒着的三角形~ 这个倒着的三角形处理实际上跟上面讲的一样,不过如果正三角形是正推那倒三角形就倒推,如果正三角形倒推那倒三角形就正推啦~
下面附上AC代码:
题意:
题目给了一张地图,地图上的数字表示猴子走到这点后能够取得的香蕉数目,猴子只能从自己当前位置向下一行的相邻位置转移,求得到最多的香蕉的数量
这道题跟数字三角形是一个意思的,只是这道题的走的图形不是一个三角形而是菱形,菱形相当于一个正的三角形和一个倒着的三角形拼接而成的。
我们来看菱形的上部分,用dp[i][j]表示在i,j位置得到的最大的香蕉数量.
如果从上往下推:不难发现对于每个边缘的位置,只能从它的上一行的一个位置推下来,比如dp[2][1]位置,只能由dp[1][1]走下来,而dp[3][3]只能由dp[2][2]走下来,而除了dp[i][1]和dp[i][i]这样的边界位置,其余的位置都是由上一行的相邻两个位置推出的,这就涉及到了边界处理
转移方程为:
if(j == 1) dp[i][j] = dp[i - 1][j] + map[i][j];
if (j == i) dp[i][j] = dp[i - 1][j - 1] + map[i][j];
else dp[i][j] = max(dp[i - 1][j - 1], dp[i - 1][j]) + map[i][j];
如果倒着推:不难发现,对于每一个元素,都是由下一行的两个相邻位置转移过来的, 所以不存在边界处理,我想这就是为啥在做数字三角形的时候,大佬们选择倒推的原因吧。。。
转移方程为:
dp[i][j] = max(dp[i + 1][j], dp[i + 1][j + 1]) + map[i][j];
很不幸,这道题不管是正着推还是倒推,都会涉及边界处理,因为这有一个倒着的三角形~ 这个倒着的三角形处理实际上跟上面讲的一样,不过如果正三角形是正推那倒三角形就倒推,如果正三角形倒推那倒三角形就正推啦~
下面附上AC代码:
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; int T, N; const int MAXN = 1e2 + 10; int map[MAXN * 2][MAXN]; int dp[MAXN * 2][MAXN]; void input() { //输入数据 for (int i = 1; i <= N; i++) { for (int j = 1; j <= i; j++) { cin >> map[i][j]; } } for (int i = N + 1; i <= 2 * N - 1; i++) { for (int j = 1; j <= 2 * N - i; j++) { cin >> map[i][j]; } } } int main() { scanf("%d", &T); int Case = 0; while (T--) { cin >> N; input(); memset(dp, 0, sizeof dp); //初始赋值 dp[2 * N - 1][1] = map[2 * N - 1][1]; //我是选择的从最后往前推,倒三角形包含边界处理 for (int i = 2 * N - 2; i >= N; i--) { for (int j = 1; j <= 2 * N - i; j++) { if (j == 1) dp[i][j] = dp[i + 1][j] + map[i][j]; else if (j == 2 * N - i) dp[i][j] = dp[i + 1][j - 1] + map[i][j]; else dp[i][j] = max(dp[i + 1][j], dp[i + 1][j - 1]) + map[i][j]; } } for (int i = N - 1; i >= 1; i--) { for (int j = 1; j <= i; j++) { dp[i][j] = max(dp[i + 1][j], dp[i + 1][j + 1]) + map[i][j]; } } cout << "Case " << ++Case << ": "; cout << dp[1][1] << endl; } return 0; }
相关文章推荐
- 【lightoj - 1004 Monkey Banana Problem (简单动规,就是数字三角形嘛。。。不过发现有个小问题)】
- lightoj 1004 - Monkey Banana Problem 【dp】
- lightOJ 1004 - Monkey Banana Problem
- LightOJ 1004 - Monkey Banana Problem
- LightOJ-1004-Monkey Banana Problem [DP]
- 在博客园安家啦~LightOJ 1004 Monkey Banana Problem (简单DP)
- LightOJ 1004 Monkey Banana Problem
- lightoj 1004 - Monkey Banana Problem
- lightoj 1004 - Monkey Banana Problem
- Lightoj 1004 - Monkey Banana Problem
- 每日刷题:lightoj-1004 - Monkey Banana Problem
- 简单递推 - 动态规划 - LightOJ - 1004 - Monkey Banana Problem
- LightOJ 1004 - Monkey Banana Problem (dp)
- LightOJ 1004 Monkey Banana Problem 动态规划
- LightOJ 1004 Monkey Banana Problem (DP 数字三角形)
- LightOJ 1004 Monkey Banana Problem (线性dp 数字菱形)
- LightOJ 1004 - Monkey Banana Problem 【DP】
- LightOJ 1004 - Monkey Banana Problem(dp)
- LightOJ 1004 - Monkey Banana Problem
- LightOJ - 1004 Monkey Banana Problem(DP)