`
Simone_chou
  • 浏览: 192762 次
  • 性别: Icon_minigender_2
  • 来自: 广州
社区版块
存档分类
最新评论

Man Down(线段树 + 区间覆盖 + DP)

    博客分类:
  • HDOJ
 
阅读更多

Man Down

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1606    Accepted Submission(s): 571


Problem Description
The Game “Man Down 100 floors” is an famous and interesting game.You can enjoy the game from
http://hi.baidu.com/abcdxyzk/blog/item/16398781b4f2a5d1bd3e1eed.html

We take a simplified version of this game. We have only two kinds of planks. One kind of the planks contains food and the other one contains nails. And if the man falls on the plank which contains food his energy will increase but if he falls on the plank which contains nails his energy will decrease. The man can only fall down vertically .We assume that the energy he can increase is unlimited and no borders exist on the left and the right.

First the man has total energy 100 and stands on the topmost plank of all. Then he can choose to go left or right to fall down. If he falls down from the position (Xi,Yi),he will fall onto the nearest plank which satisfies (xl <= xi <= xr)(xl is the leftmost position of the plank and xr is the rightmost).If no planks satisfies that, the man will fall onto the floor and he finishes his mission. But if the man’s energy is below or equal to 0 , he will die and the game is Over.

Now give you the height and position of all planks. And ask you whether the man can falls onto the floor successfully. If he can, try to calculate the maximum energy he can own when he is on the floor.(Assuming that the floor is infinite and its height is 0,and all the planks are located at different height).
 

 

Input
There are multiple test cases.

For each test case, The first line contains one integer N (2 <= N <= 100,000) representing the number of planks.

Then following N lines representing N planks, each line contain 4 integers (h,xl,xr,value)(h > 0, 0 < xl < xr < 100,000, -1000 <= value <= 1000), h represents the plank’s height, xl is the leftmost position of the plank and xr is the rightmost position. Value represents the energy the man will increase by( if value > 0) or decrease by( if value < 0) when he falls onto this plank.
 

 

Output
If the man can falls onto the floor successfully just output the maximum energy he can own when he is on the floor. But if the man can not fall down onto the floor anyway ,just output “-1”(not including the quote)
 

 

Sample Input
4
10 5 10 10
5 3 6 -100
4 7 11 20
2 2 1000 10
 

 

Sample Output

 

140

 

       题意:

       游戏规则跟“是男人就下100层”一样。给出 N (2 ~ 100000)块板,每块板都有一个高度,左端值,右端值,价值。满血的时候是100,从最高那块板开始往下垂直跳落,问到达底部时候的最大值,如果总和值小于等于 0 ,则说明不能达到,则输出 -1。

 

        思路:

        线段树 + DP + 区间覆盖 + 单点查询。DP 的时候要从高往低(正向),根据板的左右端点值所在的区域来判断能到达哪一层,如果没有任何一层可以到达则说明直接到达底部,即 0 层。首先线段树预处理每块板能到达的下一层分别是什么。所以要从最低的一层开始往上覆盖(逆向),先查询左右端点分别落在哪里,再将这块板覆盖到线段树中。然后根据公式:

        dp[ p[i].rl ] = max(dp[ p[i].rl ], dp[i] + p[ p[i].rl ].val);

        dp[ p[i].rr ] = max(dp[ p[i].rr ], dp[i] + p[ p[i].rr ].val); 来更新值,rl,rr,代表这个板的左右端点能分别到达哪块板,dp[ i ] 代表到达这块板时候的最大值。

        最后判断如果 dp [ 0 ] <= 0,则输出 -1,否则输出最大值 dp [ 0 ]。这道题的 DP 方式很像倒三角求最大和那题的 DP 方式。

        注意查询的时候,当一找到有板覆盖就返回值,否则一直找,当找到 l == r 的时候依然没有板覆盖则返回 0,说明这块板直接到达底部。

 

        AC:

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int MAX = 100005;

typedef struct {
        int h, l, r, val;
        int rl, rr;
} node;

node p[MAX];
int dp[MAX];

int cover[MAX * 3];

bool cmp(node a, node b) {
        return a.h < b.h;
}

void push_down(int node, int l, int r) {
        if (cover[node] != -1) {
                cover[node << 1] = cover[node];
                cover[node << 1 | 1] = cover[node];
                cover[node] = -1;
        }
}


void build (int node, int l, int r) {
        if (l == r) {
                cover[node] = -1;
        } else {
                int mid = (r + l) >> 1;
                build(node << 1, l, mid);
                build(node << 1 | 1, mid + 1, r);
                cover[node] = -1;
        }
}

void updata (int node, int l, int r, int cl, int cr, int c) {
        if (cl > r || cr < l) return;
        if (cl <= l && cr >= r) {
                cover[node] = c;
                return;
        }

        push_down(node, l, r);
        int mid = (r + l) >> 1;
        if (cl <= mid) updata(node << 1, l, mid, cl, cr, c);
        if (cr > mid) updata(node << 1 | 1, mid + 1, r, cl, cr, c);
}

int query (int node, int l, int r, int c) {
        if (cover[node] != -1) return cover[node];
        if (l == r && cover[node] == -1) return 0;

        push_down(node, l, r);
        int mid = (r + l) >> 1;
        if (c <= mid) return query(node << 1, l, mid, c);
        return query(node << 1 | 1, mid + 1, r, c);
}

int main() {
        int n;

        while (~scanf("%d", &n)) {
                int Max_r = 0;

                for (int i = 1; i <= n; ++i) {
                        scanf("%d%d%d%d", &p[i].h, &p[i].l, &p[i].r, &p[i].val);
                        Max_r = max(Max_r, p[i].r);
                }

                sort(p + 1, p + n + 1, cmp);

                build(1, 1, Max_r);

                for (int i = 1; i <= n; ++i) {
                        p[i].rl = query(1, 1, Max_r, p[i].l);
                        p[i].rr = query(1, 1, Max_r, p[i].r);
                        updata(1, 1, Max_r, p[i].l, p[i].r, i);
                }

                memset(dp, -1, sizeof(dp));
                dp[n] = 100 + p[n].val;
                for (int i = n; i >= 1; --i) {
                        dp[ p[i].rl ] = max(dp[ p[i].rl ], dp[i] + p[ p[i].rl ].val);
                        dp[ p[i].rr ] = max(dp[ p[i].rr ], dp[i] + p[ p[i].rr ].val);
                }

                if (dp[0] <= 0) printf("-1\n");
                else printf("%d\n", dp[0]);
        }

        return 0;
}

 

        

分享到:
评论

相关推荐

    开源项目-driusan-mandown.zip

    【开源项目-driusan-mandown.zip】是一个包含开源软件工具的压缩包,该工具名为“mandown”,专为编写man页提供便利。man页是Unix/Linux系统中用于提供命令帮助文档的传统格式,通常由特定的语法编写。然而,...

    人脸性别检测+分类数据集-含woman+man两种分类+300张高质量真实手机采集人脸图片+已做分类划分标注-可用于深度学习算法

    人脸性别检测+分类数据集_含woman+man两种分类+300张高质量真实手机采集人脸图片+已做分类划分标注_可用于深度学习算法训练

    人脸性别检测+分类数据集-含woman+man两种分类+300张高质量真实手机采集人脸图片+已做分类划分-可用于深度学习算法训练

    人脸性别检测+分类数据集_含woman+man两种分类+300张高质量真实手机采集人脸图片+已做分类划分标注_可用于深度学习算法训练

    树型DP和状态压缩DP+acm.ppt

    树型DP和状态压缩DP+acm.ppt

    man文件(busubox+mksh+linux_shell编程if中参数)

    在Linux系统中,`man`文件是用于提供命令、程序或系统调用的在线帮助文档。`busubox`和`mksh`是与Linux Shell编程相关的工具,而`if`语句是Shell脚本中常用的条件控制结构。这篇内容将深入探讨这些主题。 首先,让...

    x-man:Layui2.3+thinkphp3.2.3后台管理框架,一键增删改查,支持多表联动 http

    X-Man后台管理框架Author XinyLayui2.4.3+Thinkphp3.2.3后台管理框架,一键增删改查,支持多表外联,控件多样化,完善的权限管理模块演示地址:如果觉得对你有所帮助 请为我点个星星 谢谢数据库文件 xinyadmin.sql如...

    notpad++插件

    Notepad++是一款非常受欢迎的免费源代码编辑器,尤其在编程和文本处理领域广泛应用。它支持多种编程语言,并且可以通过安装各种插件来扩展其功能。"notpad++插件"指的是为Notepad++设计的特定插件,用于增强其原有...

    Notepad++ sql格式化插件 Poor Man's T-SQL Formatter 1.5.1

    "Poor Man's T-SQL Formatter 1.5.1"就是一个专门为Notepad++设计的SQL格式化插件,能够帮助用户快速而准确地格式化Transact-SQL(T-SQL)代码。 这个插件的名称“Poor Man's T-SQL Formatter”暗示了它的目标是为...

    Pac-Man:使用C ++和SFML制作的Pac-Man游戏克隆

    使用C ++和SFML制作的Pac-Man游戏克隆。描述:游戏由一个包含点,超级点和奖励水果的迷宫组成。玩家的目标是在吃豆人中穿越迷宫并收集所有点,而不会被鬼魂抓到。特征:记分板显示前10个得分具有挑战性的游戏体验,...

    X-man地图.rar

    x-man系列地图不用介绍了吧。下面是地图列表 x-man2003 x-man2003.bsp X-man2003b.bsp x-man2004b.bsp x-man2004c.bsp X-man2006.bsp X-man2007.bsp X-man2008.bsp X-man2009.bsp X-man2010.bsp X-man2011Benladen....

    Bomberman:C ++中的Bomberman游戏(学校项目)

    《C++实现的Bomberman游戏详解》 Bomberman是一款经典的街机游戏,以其独特的对战模式和策略性玩法深受玩家喜爱。在这个学校项目中,我们以C++编程语言来实现这一经典游戏,旨在加深对游戏编程的理解,锻炼逻辑思维...

    爬虫-Spiderman+WebCollector

    爬虫-Spiderman+WebCollector Spiderman2 Web Collector Spiderman2 WebCollector 爬虫-Spi derman+WebCollector 爬虫-Spiderman+WebColl ector 爬虫-Spiderman+WebCollector 爬虫-Spide rman+WebCollector

    人月神话(the mythical man month)中文版+英文版

    书名中的"Man-Month"概念是作者提出的一个关键观点,意指在软件开发项目中,简单地增加人员并不等同于按比例增加工作产出,反而可能导致效率下降,因为增加了沟通和协调的成本。这本书在1975年首次出版,至今仍对IT...

    MAN+B&W+主机FIVA+故障诊断分析.doc

    "MAN+B&W+主机FIVA+故障诊断分析" FIVA 阀是一种电液比例阀,是 ME 型柴油机的电喷系统中控制喷油定时和喷油量以及喷油压力的核心部件。其启闭动作由柴油机电控系统中的 CCU 通过分析曲轴转角传感器和转速传感器...

    mandown:手册页启发的Markdown查看器

    **mandown:手册页启发的Markdown查看器** `mandown` 是一个专为终端用户设计的 Markdown 查看器,它的灵感来源于传统的 Linux 手册页(man pages)。这个工具允许用户在命令行界面(CLI)中以优雅的方式浏览和阅读...

    FreemanDurden.zip_Freeman-Durden分解_Freeman分解_durden_freeman_zip

    Freeman-Durden极化分解代码

    bomberman:在C ++和OpenGL中经典游戏轰炸机的娱乐

    炸弹人 一个用C ++编写的具有ECS设计和用OpenGL实现的图形的3D轰炸机致敬游戏。 包含8个级别,可播放4个主题。 入门 ... 建造 make deps make ... 文献资料 要求: doxygen &gt;= 1.8.4 Python 3.6例如在MacOS上。...

    man手册 中文版

    在Linux操作系统中,`man`手册是每个程序员和系统管理员不可或缺的工具,它提供了系统命令、函数库、配置文件和程序的详细文档。这个“man手册中文版”压缩包文件显然是为那些希望以中文阅读文档的用户设计的,旨在...

    Linux中文man在线手册

    Linux中文man在线手册 Linux中文man在线手册 Linux中文man在线手册 Linux中文man在线手册

    win$man通用安装器

    "win$man通用安装器"是一款专为Windows操作系统设计的自动化安装工具,主要适用于Windows 7及Windows XP/2003系统。该工具旨在简化系统安装过程,提高IT管理员或者普通用户在部署操作系统时的效率。从描述来看,这个...

Global site tag (gtag.js) - Google Analytics