巧接人参果
题目描述
唐僧率领徒弟孙悟空、猪八戒、沙和尚去西天取经,路经万寿山五庄观。 观主镇元大仙上天听道去
了,临行嘱咐童子,大唐高僧路经此地,可取人参果好生款待。这人参果乃仙家之宝 ,食之能长生
不老。师徒一行来到五庄观,观中童儿只将人参果款待唐僧 。悟空不甘受此冷落,加之贪吃的八戒
在旁怂恿,便潜入果园偷吃人参仙果。 恰巧你也在那,于是你有缘与孙悟空一起摘人参果。不过这
人参果遇金则落,遇土则遁。为此,孙悟空、猪八戒、沙和尚三人爬上果树用金箍棒等将人参果打落
,而你则在树底下接人参果。 这人参果别处都不掉,就掉落在他身旁的10米范围内。人身果如果掉
在了地上就不见了。当然你很聪明,可是看到这么多人身果,动作也变迟钝了,每秒种只有在移动不
超过一米的范围内接住坠落的人身果。现在给你接人参果如图标上坐标: 为了使问题简化,假设在
接下来的一段时间里,人参果都掉落在0-10这11个位置。开始时你站在5这个位置,因此在第一秒,
他只能接到4,5,6这三个位置中期中一个位置上的人参果。问你最多可能接到多少个人参果?(假设
背包可以容纳无穷多个人参果)
输入
输入数据有多组。每组数据的第一行为以正整数n(0 < n < 100000),表示有n个人参果掉下来
。在接下来的n行中,每行有两个整数x,T(0 <= T < 100000),表示在第T秒有一个人参果掉在
x点上。同一秒钟在同一点上可能掉下多个人参果。n=0时输入结束。
输出
每一组输入数据对应一行输出。输出一个整数m,表示你最多可能接到m个人参果。
样例输入
6
5 1
4 1
6 1
7 2
7 2
8 3
0
样例输出
4
题解:
DP(动态规划),稍复杂一丢丢。
定义dp[i][j]为第i秒,第j个位置时最大馅饼数;对于当前位置,我们的上一个位置有三种状态,当前位置、当前位置左边、当前位置右边(只有这三个位置在1秒内能移动到当前位置),加上本状态的馅饼,即为当前状态的馅饼数;如果这个数比最大值要大就取这个数;
对于dp数组,我们选择前一维参数为时间,后一维参数为位置;因为每一个状态计算时需要用到前一时间状态的三个位置,所以要用位置进行内循环来求解(如果我们知道某一位置的三个时间是无法求解的);
我们需要初始化第一秒时dp状态,从第二秒开始循环求解;同时我们需要知道最大时间才能往前推,所以要记录最大时间;
注意输入时的参数顺序;用开始时给定位置的自加记录到某个位置时掉落的馅饼数数量。
源代码:
#include<bits/stdc++.h>
using namespace std;
int dp[100010][15],n,x,tim,i,j;
int main() {
while(~scanf("%d",&n)&&n!=0) {
int check=0;
memset(dp,0,sizeof(dp));
for(i=1; i<=n; i++) {
cin>>x>>tim;
dp[tim][x]++;
check=max(check,tim);
}
for(i=check-1; i>=0; i--) {
for(j=0; j<=10; j++) {
int max1=max(dp[i+1][j],dp[i+1][j-1]);
dp[i][j]=dp[i][j]+max(max1,dp[i+1][j+1]);
}
}
printf("%d\n",dp[0][5]);
}
return 0;
}