任务描述
都说天上不会掉馅饼,但有一天 Gameboy 正走在回家的小径上,忽然天上掉下大把大把的馅饼。说来 Gameboy 的人品实在是太好了,这馅饼别处都不掉,就掉落在他身旁的 10m
范围内。馅饼如果掉在地上,当然就不能吃了,所以 Gameboy 马上卸下身上的背包去接。但由于小径两侧都不能站人,所以他只能在小径上接。由于 Gameboy 平时老待在房间里玩游戏,虽然在游戏中是个身手敏捷的高手,但在现实中运动神经特别迟钝,每秒只有在移动不超过 1m 的范围内接住坠落的馅饼。现在给这条小径标上坐标,如图 1 所示。
为了简化问题,假设在接下来的一段时间里,馅饼都掉落在 0~10
这 11 个位置。开始时 Gameboy 站在位置 5
,因此在第 1
秒,他只能接到 4、5、6
这 3 个位置中 1 个位置上的馅饼。 问 Gameboy 最多可能接到多少个馅饼(假设他的背包可以容纳无穷多个馅饼)?
编程要求
根据提示,在右侧编辑器补充代码。
测试说明
Time limit 1000 ms Mem limit 32768 kB
平台会对你编写的代码进行测试:
测试输入:
6
5 1
4 1
6 1
7 2
7 2
8 3
0
预期输出: 4
试题来源
HDU 1176
解题思路:
3s | 1 | |||||||||
2s | 2 | |||||||||
1s | 1 | 1 | 1 | |||||||
位置 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
由题意可知gameboy每回只能接到下一秒来自他左右和本身位置的馅饼,如上图所示,因此要想知道从5位置开始最多能拿到多少馅饼就需要知道他上方的位置能获得最多的馅饼数量,因此就要从最后一秒开始往下算,计算出每个位置最多能拿到的馅饼数量,引用二维数组dp,来记录位置和馅饼数量
代码:
#include<iostream>
#include<string.h>
using namespace std;
int exactly[100110][12];
int dp[100110][12];
main()
{
int n;
int i,i1;
int row,col;
while(scanf("%d",&n),n){
int maxx=0,mmax;
memset(exactly,0,sizeof(exactly));//重置
memset(dp,0,sizeof(dp));
for(i=1;i<=n;i++){
scanf("%d %d",&row,&col);
exactly[col][row]++;
if(col>maxx)
maxx=col;}
for(i=0;i<=10;i++)
dp[maxx][i]=exactly[maxx][i];
for(i=maxx-1;i>=0;i--){//层层向下计算
for(i1=0;i1<=10;i1++){
mmax=0;
if(i1-1>=0){
mmax=dp[i+1][i1-1];
}
if(dp[i+1][i1]>mmax)
mmax=dp[i+1][i1];
if(dp[i+1][i1+1]>mmax&&(i1+1<=10))
mmax=dp[i+1][i1+1];
dp[i][i1]=exactly[i][i1]+mmax;
}
}
printf("%d\n",dp[0][5]);
}
return 0;
}