HDU 1176免费馅饼来自 动态规划DP

任务描述

都说天上不会掉馅饼,但有一天 Gameboy 正走在回家的小径上,忽然天上掉下大把大把的馅饼。说来 Gameboy 的人品实在是太好了,这馅饼别处都不掉,就掉落在他身旁的 10m 范围内。馅饼如果掉在地上,当然就不能吃了,所以 Gameboy 马上卸下身上的背包去接。但由于小径两侧都不能站人,所以他只能在小径上接。由于 Gameboy 平时老待在房间里玩游戏,虽然在游戏中是个身手敏捷的高手,但在现实中运动神经特别迟钝,每秒只有在移动不超过 1m 的范围内接住坠落的馅饼。现在给这条小径标上坐标,如图 1 所示。

为了简化问题,假设在接下来的一段时间里,馅饼都掉落在 0~1011 个位置。开始时 Gameboy 站在位置 5,因此在第 1 秒,他只能接到 4、5、63 个位置中 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

解题思路:

3s1
2s2
1s111
位置12345678910

由题意可知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; 
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值