DP(1) --- 数塔
来源:互联网 发布:js 业务逻辑 模块 编辑:程序博客网 时间:2024/06/15 18:01
数塔问题
1. 基本模型 (HDU 2084)
如上图所示数塔,要求从顶层走到底层,若每一步只能走到相邻的结点,则经过的结点的数字之和最大是多少?
数塔思想:自顶向下分析,自底向上计算。
H(i) 表示第i层的最大值。要得到H(i + 1),则考虑上一层结点,到其相邻节点可取得的值,取最大值作为H(i + 1)。
如果按照上述做法,从顶到底算起,则时间复杂度为 O(2^(n – 1));
考虑从底部算起,计算每个结点到底层的最大值,即上一层结点与其相邻节点的最大值,以这个最大值作为上一层结点的值,重复这一过程,直到塔顶。时间复杂度为O(n)
2. 简单应用
a. 多少条路径 (HDU 2151)
猴子爬树,最初猴子在第一棵树上,每过一分钟,猴子会跳到相邻的树上。现在这里有n棵树,求过了m分钟,有多少种不同的跳法跳到第T棵树。(HDU2151)考虑以下图形, 是不是很像一个数塔?
![](http://img.my.csdn.net/uploads/201210/04/1349308587_5315.JPG)
b. 多顶点型数塔(例题 HDU 1176)
免费馅饼,有0—10个位置,起始时,人在5处,每一秒都会有几个馅饼落下来,每秒人可以移动到相邻的位置,问最多可以接多少个馅饼?考虑如下算法:
dp[i][j] 表示从第i秒起第j个位置可得到的馅饼;
pie[i][j] 表示第i秒第j个位置落下的馅饼
从最后一秒算起,dp[i][j] = max(dp[i + 1][j], max(dp[i + 1][j - 1], dp[i + 1][j + 1]))+ pie[i][j]
重复这一过程知道t = 0;最后这会形成一个多顶点的数塔,每个位置都是一个顶点。
3. 例题代码
HDU 2084
#include <stdio.h>int tower[100][100];int main(){int i, j;int T, N;int v1, v2;scanf ("%d", &T);while (T --){scanf ("%d", &N);for (i = 1; i <= N; i ++){for (j = 1; j <= i; j ++){scanf ("%d", &tower[i][j]);}}for (i = N - 1; i >= 1; i --) // 自底向上计算每一层的最大值{for (j = 1; j <= i + 1; j ++){v1 = tower[i + 1][j] + tower[i][j];v2 = tower[i + 1][j + 1] + tower[i][j];tower[i][j] = v1;if (v1 < v2){tower[i][j] = v2;}}}printf ("%d\n", tower[1][1]);}return 0;}
HDU 2151
#include <stdio.h>#include <string.h>int main(){int i, j, k;int numbers;int N, P, M, T;int tree[2][101];int times[2][101];while (scanf ("%d%d%d%d", &N, &P, &M, &T) == 4){memset (times, 0, sizeof (times));tree[0][0] = P;times[0][P] = 1;numbers = 1;k = 0;while (M --){j = 0;k %= 2;for (i = 0; i < numbers; i ++){if (tree[k][i] > 1){if (times[k ^ 1][tree[k][i] - 1] == 0){tree[k ^ 1][j ++] = tree[k][i] - 1;}times[k ^ 1][tree[k][i] - 1] += times[k][tree[k][i]];}if (tree[k][i] < N){if (times[k ^ 1][tree[k][i] + 1]== 0){tree[k ^ 1][j ++] = tree[k][i] + 1;}times[k ^ 1][tree[k][i] + 1] += times[k][tree[k][i]];}times[k][tree[k][i]] = 0;}numbers = j;k ++;}printf ("%d\n", times[k % 2][T]);}return 0;}
HDU 1176
#include <stdio.h>#include <string.h>#define MAX 100002int pie[MAX][13];int dp[MAX][13];int max_v (int a, int b);int main(){int n;int i, j;int t, x;int max_t;while (scanf ("%d", &n) == 1 && n){memset (pie, 0, sizeof (pie));memset (dp, 0, sizeof (dp));max_t = 0;for (i = 0; i < n; i ++){scanf ("%d%d", &x, &t);if (max_t < t){max_t = t;}pie[t][x + 1] ++;}for (i = max_t; i >= 0; i --){for (j = 1; j < 12; j ++){dp[i][j] = max_v (dp[i + 1][j - 1], max_v (dp[i + 1][j], dp[i + 1][j + 1])) + pie[i][j];}}printf ("%d\n", dp[0][6]);}return 0;}int max_v (int a, int b){if (a > b){return a;}return b;}
- DP(1) --- 数塔
- 数塔(Dp)
- 数塔(DP)
- 数塔(dp)
- 数塔 (dp)
- 数塔 (dp)
- 数塔(dp)
- HDU 数塔 (dp)
- 数塔2(dp)
- hdoj2084数塔(dp)
- hdu2084数塔(DP)
- hdu2084 数塔 (DP)
- 数塔 (dp水题)
- 数塔 (dp)HDU
- 数塔(简单DP)
- HDOJ2084 数塔(DP)
- 数塔(DP练习)
- (hdu2084)数塔(DP)
- Html之【超链接<A>】综合技巧大全(持续更新中..)
- Html之【文字格式标签】综合技巧大全(持续更新中...)
- .Net中TextBox对于焦点的控制
- SendKeys.Send()的使用
- 不用中间变量交换两个数的陷阱
- DP(1) --- 数塔
- 【数据结构】链表
- 蛇形填 数
- 使用Eclipse WTP工具部署Maven管理的Web应用
- 水仙花数
- 项目延期原因及应对之道
- (1)21.1并发的多面性
- HDU 3231 Box Relations(拓扑排序)
- 百度系统研发笔试题