、
#include<stdio.h>
#include<iostream>
#include<string.h>
using namespace std;
int dp[15][100005];
int min_t=0x3f3f3f3f;
int max_t=0;
int main ()
{
int n,a,b;
while(scanf("%d",&n)==1&&n!=0)
{
memset(dp,0,sizeof(dp));
while(n--)
{
scanf("%d%d",&a,&b);
dp[a+1][b]++;
if(b>max_t)
{
max_t=b;
}
if(b<min_t)
{
min_t=b;
}
}
for(int i=max_t-1;i>=min_t-1;i--)
{
for(int j=1;j<=11;j++) //注意一下。提前一位-.-要不还得多注意一步0.
{
dp[j][i]+=max(max(dp[j-1][i+1],dp[j+1][i+1]),dp[j][i+1]);
}
}
printf("%d\n",dp[6][min_t-1]);
}
return 0;
}
解析:怎么来分析这道题的思路,我们来看题干的中的这段话“gameboy站在5这个位置,因此在第一秒,他只能接到4,5,6这三个位置中其中一个位置上的馅饼”这句话就告诉我们了 5可以接住4,5,6三个位置的馅饼,那么以此类推。我们反过来想一下。站在分别站在4,5,6的位置去接馅饼。他的前一秒就是5的位置。那我们要找到最大的(也就是能接最多馅饼的位置,我们就可以从4,5,6三个位置中间挑出最大的)就是这个思想,我们往下扩展,1 2 3—>2.等等。。渐渐我们就可以得到递推式
dp[j][i]+=max(max(dp[j-1][i+1],dp[j+1][i+1]),dp[j][i+1])
这个J代表位置。I代表时间。清空数组,每次输入时间和地点的时候就让dp[j][i]++这样就可以记录i时间j地点会掉下来几张馅饼。然后按照时间从后往前的顺序推。(为什么从后往前,因为我们是试拿4,5,6去推5这种操作)I时间和J地点掉落的馅饼一定要对应好。
此外注意一下0位置。因为我们的DP式存在dp[j-1][i=1],所以0的这个位置比较特殊。我这里采取的方法是整体加1.也就是0对应1. 1对应2,5对应6。时间我们存一下最小的。存一下最大的。也是是开始掉落的和最后掉落。然后递推。最后输出一下我们想要的就可以了。因为最开始站在5的位置。所以我们输出dp[6][min_t-1]即可。