为了使问题简化,假设在接下来的一段时间里,馅饼都掉落在0-10这11个位置。开始时gameboy站在5这个位置,因此在第一秒,他只能接到4,5,6这三个位置中其中一个位置上的馅饼。问gameboy最多可能接到多少个馅饼?(假设他的背包可以容纳无穷多个馅饼)
Output每一组输入数据对应一行输出。输出一个整数m,表示gameboy最多可能接到m个馅饼。
提示:本题的输入数据量比较大,建议用scanf读入,用cin可能会超时。
Sample Input
6 5 1 4 1 6 1 7 2 7 2 8 3 0Sample Output
4
给了很多第t秒在第x位置会出现的馅饼,然后每次移动只有三种操作:向左移一个接住、不动接住、向右移一下接住(注意0点只能不动和右移,10点只能不动和左移)。然后状态转移方程 : dp[i][j] = dp[i][j] + max ( dp[i+1][j-1], dp[i+1][j] , dp[i+1][j+1] ) 本题需要从最后时刻的位置往前递推,因为要使答案最大,需要从后往前推,才能保证到最开始的点是最大的
代码如下:
#include<stdio.h>
#include<iostream>
#include<string.h>
using namespace std;
const int maxn = 100000;
int dp[maxn][12];
int main()
{
int n;
while(scanf("%d", &n) != EOF)
{
if(n == 0) break;
memset(dp, 0, sizeof(dp));
int t = -1;
for(int i = 0; i < n; i ++)
{
int x, T;
scanf("%d%d", &x, &T);
dp[T][x] ++;
if(t < T)
{
t = T;
}
}
for(int i = t-1; i >= 0; i--)
{
for(int j = 0; j <= 10; j ++)
{
if(j == 0)
{
dp[i][j] += max(dp[i+1][j], dp[i+1][j+1]);
}
else if(j == 10)
{
dp[i][j] += max(dp[i+1][j], dp[i+1][j-1]);
}
else
{
dp[i][j] += max(max(dp[i+1][j], dp[i+1][j-1]), dp[i+1][j+1]);
}
}
}
int ans = dp[0][5];
printf("%d\n",ans);
}
return 0;
}