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
6
5 1
4 1
6 1
7 2
7 2
8 3
0
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;
}