HDU 1176(类似数字三角形的题,很经典,值得仔细理解的dp思维)

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=1176

免费馅饼

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 60927    Accepted Submission(s): 21380

Problem Description

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

为了使问题简化,假设在接下来的一段时间里,馅饼都掉落在0-10这11个位置。开始时gameboy站在5这个位置,因此在第一秒,他只能接到4,5,6这三个位置中其中一个位置上的馅饼。问gameboy最多可能接到多少个馅饼?(假设他的背包可以容纳无穷多个馅饼)

Input

输入数据有多组。每组数据的第一行为以正整数n(0<n<100000),表示有n个馅饼掉在这条小径上。在结下来的n行中,每行有两个整数x,T(0<T<100000),表示在第T秒有一个馅饼掉在x点上。同一秒钟在同一点上可能掉下多个馅饼。n=0时输入结束。

Output

每一组输入数据对应一行输出。输出一个整数m,表示gameboy最多可能接到m个馅饼。
提示:本题的输入数据量比较大,建议用scanf读入,用cin可能会超时。

Sample Input

6

5 1

4 1

6 1

7 2

7 2

8 3

0

Sample Output

4

分析:

一开始真的不知道是个数字三角形的变形题,思考了很久,最后看了别人的题解。。。。。。。

分析:

一个人站在5的位置

第一秒能到的位置:4,5,6

第二秒能到的位置:3,4,5,6,7

第三秒能到达的位置:2,3,4,5,6,7,8

依次类推:

第一秒:                       4,5,6

第二秒:                 3,4,5,6,7

第三秒:           2,3,4,5,6,7,8

第四秒:     1,2,3,4,5,6,7,8,9

第五秒:0,1,2,3,4,5,6,7,8,9,10

第六秒:0,1,2,3,4,5,6,7,8,9,10

非常的类似数字三角形,回顾一下数字三角形:从顶向下走(只能向下或者左下),怎么走使得走过的路权值之和最大

回到这个问题,这个问题的权值就是某个时刻某个位置馅饼的个数

dp[i][j]:第i秒j位置馅饼的个数

是不是非常非常类似数字三角形?

每次移动的话只要三个选择:向左一个单位,向右一个单位,不动

所以状态转移方程:

dp[i][j]=max(dp[i+1][j],max(dp[i+1][j-1],dp[i+1][j+1]))+dp[i][j];

跟数字三角形一样,倒推

注意初始化:

dp数组初始化为0,表示一开始所有时刻,所有位置馅饼个数为0

每个时刻每个位置馅饼的个数要随着输入写好

找到时刻的最大值,这样从时刻最大值倒数循环

代码如下:

#include<bits/stdc++.h>
using namespace std;
#define max_v 100005
int dp[max_v][20];
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        if(n==0)
            break;
        memset(dp,0,sizeof(dp));
        int t=-1;
        for(int i=0;i<n;i++)
        {
            int x,y;
            scanf("%d %d",&x,&y);
            dp[y][x]++;
            if(y>t)
                t=y;
        }
        for(int i=t-1;i>=0;i--)
        {
            for(int j=10;j>=0;j--)
            {
                dp[i][j]=max(dp[i+1][j],max(dp[i+1][j-1],dp[i+1][j+1]))+dp[i][j];
            }
        }
        printf("%d\n",dp[0][5]);
    }
    return 0;
}

  

原文地址:https://www.cnblogs.com/yinbiao/p/9157535.html

时间: 2024-10-09 03:26:44

HDU 1176(类似数字三角形的题,很经典,值得仔细理解的dp思维)的相关文章

数字三角形合集

简单介绍 数字三角形这东西,出现了有一定的年头了.于是,出现了一些变种-- 眼下已知的题目 Codevs1220 数字三角形 这题是原版IOI1994啊-- f[i][j]=a[i][j]+max(f[i-1][j],f[i-1][j-1]). Codevs2193 数字三角形ww 和 Codevs2198 数字三角形www 改了.必须得经过一个点.而且2198是2193的数据规模上的加强版. 然而这并没有什么L用,仅仅需让必须经过的点的权值加上一个特别大的值,最后的结果再减去这个值即可了. 实

HDU 2091 空心三角形 --- 水题

/* HDU 2091 空心三角形 --- 水题 */ #include <cstdio> int main() { int kase = 0; char ch; int h, t; //h表示高 while (scanf("%c", &ch) == 1 && ch != '@'){ scanf("%d", &h); if (kase++){ printf("\n"); } getchar(); if

HDU 2178.猜数字【分析能力练习】【读题能力联系】【8月10】

猜数字 Problem Description A有1数m,B来猜.B每猜一次,A就说"太大","太小"或"对了" . 问B猜n次可以猜到的最大数. Input 第1行是整数T,表示有T组数据,下面有T行 每行一个整数n (1 ≤ n ≤ 30) Output 猜n次可以猜到的最大数 Sample Input 2 1 3 Sample Output 1 7 哎呀妈呀,这题什么意思啊!-----第一感觉 仔细理解理解:比如数据中的3次可以最大猜到7

做题记录: P1118 [USACO06FEB]数字三角形Backward Digit Su…

P1118 [USACO06FEB]数字三角形Backward Digit Su- /*思路:设一开始的n个数为a1.a2.a3...an, 一步一步合并就可以用a1..an表示出最后剩下来 的数,不难发现其中a1..an的系数恰好就是第n层 杨辉三角中的数.所以我们可以先处理出第n层杨 辉三角中的数,然后根据这一层中的数搜索即可.*/ #include<iostream> #include<cstdio> #include<fstream> #include<a

蓝桥算法训练 数字三角形 ALGO-124(数塔,经典dp)(hdu 2084)

问题描述 (图3.1-1)示出了一个数字三角形. 请编一个程序计算从顶至底的某处的一条路 径,使该路径所经过的数字的总和最大. ●每一步可沿左斜线向下或右斜线向下走: ●1<三角形行数≤100: ●三角形中的数字为整数0,1,…99: . (图3.1-1) 输入格式 文件中首先读到的是三角形的行数. 接下来描述整个三角形 输出格式 最大总和(整数) 样例输入 573 88 1 02 7 4 44 5 2 6 5 样例输出 30 #include <algorithm> #include

HDU 1176免费馅饼 DP数塔问题转化

L - 免费馅饼 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Practice HDU 1176 Appoint description:  prayerhgq  (2015-07-28) System Crawler  (2015-11-21) Description 都说天上不会掉馅饼,但有一天gameboy正走在回家的小径上,忽然天上掉下大把大把的馅饼.

P1044 - 数字三角形

P1044 - 数字三角形 From Admin    Normal (OI)总时限:10s    内存限制:128MB    代码长度限制:64KB 背景 Background 09年 USACO 11月月赛  铜牌第一道 描述 Description 示出了一个数字三角形. 请编一个程序计算从顶至底的某处的一条路径,使该路径所经过的数字的总和最大. 每一步可沿左斜线向下或右斜线向下走: 1<三角形行数<25: 三角形中的数字为整数<1000: 输入格式 InputFormat 第一行

回档|数字三角形2

描述 数字三角形 要求走到最后mod 100最大 输入格式 第1行n,表示n行 <=25 第2到n+1行为每个的权值 输出格式 mod 100最大值 测试样例1 输入 2 1 99 98 输出 99 题目分析: 数字三角形是一道经典的题目,因此它有许多强化版本.我做了2——4.虽然他们大同小异,我还是发上来,以便大家扩充思路.(其实我的代码p,c交互是有原因的,因为我暑假开始转C,同时才开始刷题,所以有的题是P,有的题是C) 那么回到正题.这道题我用了一个三维的布尔数组f[i][j][k].利用

数字三角形——递归、递推、记忆化搜索

数字三角形 描述: 有一个由非负整数组成的三角形,第一行只有一个数,除了最下行之外没个数的左下方和右下方各有一个数. 问题: 从第一行的数开始,每次可以往左下或右下走一格,直到走到最下行,把沿途经过的数全部加起来.如何走才能使得这个和尽量大? 分析: 不难看出此题是一个动态的决策问题:每次有两种选择--左下或右下.如果用回溯法求出所有的可能的路线,就可以从中选出最优的路线.但和往常一样,回溯法的效率太低:一个n层数字三角形的完整路线有2^n条,当n很大时回溯法的速度将让人无法忍受.因此本题讨论用