
本文共 2494 字,大约阅读时间需要 8 分钟。
DP(数塔问题) - 免费馅饼 - HDU - 1176
题意:
有 11 个 位 置 0 , 1 , 2 , . . . , 10 , 初 始 时 站 在 5 号 位 置 , 每 秒 钟 可 以 向 任 意 方 向 移 动 一 个 长 度 单 位 , 有11个位置0,1,2,...,10,初始时站在5号位置,每秒钟可以向任意方向移动一个长度单位, 有11个位置0,1,2,...,10,初始时站在5号位置,每秒钟可以向任意方向移动一个长度单位,
给 定 n 个 行 数 据 , 每 行 包 括 两 个 整 数 x 和 t , 表 示 在 t 时 刻 x 位 置 , 有 一 个 馅 饼 , 给定n个行数据,每行包括两个整数x和t,表示在t时刻x位置,有一个馅饼, 给定n个行数据,每行包括两个整数x和t,表示在t时刻x位置,有一个馅饼,
要 计 算 从 5 出 发 , 最 多 能 够 获 得 多 少 个 馅 饼 。 要计算从5出发,最多能够获得多少个馅饼。 要计算从5出发,最多能够获得多少个馅饼。
输入:
多 组 测 试 数 据 , 多组测试数据, 多组测试数据,
每 组 包 括 一 个 正 整 数 n 每组包括一个正整数n 每组包括一个正整数n
接 着 n 行 , 每 行 两 个 正 整 数 x 和 t 接着n行,每行两个正整数x和t 接着n行,每行两个正整数x和t
输出:
一 个 正 整 数 , 表 示 获 得 馅 饼 的 最 大 数 量 。 一个正整数,表示获得馅饼的最大数量。 一个正整数,表示获得馅饼的最大数量。
Sample Input
65 14 16 17 27 28 30
Sample Output
4
数据范围:
0 < n , t < 100000 0<n,t<100000 0<n,t<100000
分析:
如 下 图 : 如下图: 如下图:
当 t > = 6 时 , 是 事 实 上 可 以 从 5 走 到 0 到 10 的 任 意 位 置 。 当t>=6时,是事实上可以从5走到0到10的任意位置。 当t>=6时,是事实上可以从5走到0到10的任意位置。
如 果 我 们 反 过 来 考 虑 , 这 就 是 一 个 数 塔 问 题 。 如果我们反过来考虑,这就是一个数塔问题。 如果我们反过来考虑,这就是一个数塔问题。
我 们 记 w [ i ] [ j ] : 表 示 i 时 刻 在 j 位 置 处 的 馅 饼 数 量 。 f [ i ] [ j ] : 表 示 t 时 刻 在 j 位 置 处 最 多 能 够 获 得 的 馅 饼 数 量 。 我们记w[i][j]:表示i时刻在j位置处的馅饼数量。f[i][j]:表示t时刻在j位置处最多能够获得的馅饼数量。 我们记w[i][j]:表示i时刻在j位置处的馅饼数量。f[i][j]:表示t时刻在j位置处最多能够获得的馅饼数量。
如 果 我 们 自 底 向 上 考 虑 , 每 个 点 的 最 大 值 都 取 决 于 下 方 连 续 的 2 或 3 个 点 的 最 大 值 。 如果我们自底向上考虑,每个点的最大值都取决于下方连续的2或3个点的最大值。 如果我们自底向上考虑,每个点的最大值都取决于下方连续的2或3个点的最大值。
即 : f [ i ] [ j ] = m a x ( f [ i + 1 ] [ j − 1 ] , f [ i + 1 ] [ j ] , f [ i + 1 ] [ j + 1 ] ) + w [ i ] [ j ] 即:f[i][j]=max(f[i+1][j-1],f[i+1][j],f[i+1][j+1])+w[i][j] 即:f[i][j]=max(f[i+1][j−1],f[i+1][j],f[i+1][j+1])+w[i][j]
那 么 终 点 就 是 0 时 刻 在 起 点 位 置 5 的 值 。 那么终点就是0时刻在起点位置5的值。 那么终点就是0时刻在起点位置5的值。
考 虑 到 边 界 问 题 , 为 了 简 化 代 码 , 把 所 有 位 置 向 右 平 移 1 个 长 度 单 位 。 考虑到边界问题,为了简化代码,把所有位置向右平移1个长度单位。 考虑到边界问题,为了简化代码,把所有位置向右平移1个长度单位。
代码:
#include<cstdio>#include<iostream>#include<cstring>#include<vector>#include<queue>using namespace std;const int N=100010;int f[N][15];int n;int w[N][15];int t, x;int main(){ while(~scanf("%d",&n),n) { memset(w,0,sizeof w); memset(f,0,sizeof f); int T=0; for(int i=0;i<n;i++) { scanf("%d%d",&x,&t); w[t][x+1]++; T=max(T,t); } for(int i=1;i<=11;i++) f[T][i]=w[T][i]; for(int i=T-1;i>=0;i--) for(int j=1;j<=11;j++) { f[i][j]=max(f[i+1][j],max(f[i+1][j-1],f[i+1][j+1]))+w[i][j]; } printf("%d\n",f[0][6]); } return 0;}
发表评论
最新留言
关于作者
