HDU 3016 Man Down 线段树+简单DP

囧,一开始看错题意,后来才发现人是垂直下落的,被附带链接里的Man Down游戏误导了。

那就变成了一个简单的DAG模型动态规划,随意搞就ok了

#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <set>
#include <vector>
#include <string>
#include <queue>
#include <deque>
#include <bitset>
#include <list>
#include <cstdlib>
#include <climits>
#include <cmath>
#include <ctime>
#include <algorithm>
#include <stack>
#include <sstream>
#include <numeric>
#include <fstream>
#include <functional>

using namespace std;

#define MP make_pair
#define PB push_back
#define lson rt << 1,l,mid
#define rson rt << 1 | 1,mid + 1,r
typedef long long LL;
typedef unsigned long long ULL;
typedef vector<int> VI;
typedef pair<int,int> pii;
const int INF = INT_MAX / 3;
const double eps = 1e-8;
const LL LINF = 1e17;
const double DINF = 1e60;
const int maxn = 1e5 + 10;

struct Plank {
    int h,l,r,power;
    Plank(int h,int l,int r,int power): h(h),l(l),r(r),power(power) {}
    bool operator < (const Plank &p) const {
        return h < p.h;
    }
};

vector<Plank> plank;
int n,Val[maxn << 2],lazy[maxn << 2];
LL f[maxn];

void pushdown(int rt) {
    if(lazy[rt] == -1) return;
    Val[rt << 1] = Val[rt << 1 | 1] =
        lazy[rt << 1] = lazy[rt << 1 | 1] = lazy[rt];
    lazy[rt] = -1;
}

void update(int rt,int l,int r,int ql,int qr,int v) {
    if(ql <= l && qr >= r) {
        Val[rt] = v; lazy[rt] = v;
    }
    else {
        int mid = (l + r) >> 1;
        pushdown(rt);
        if(ql <= mid) update(lson,ql,qr,v);
        if(qr > mid) update(rson,ql,qr,v);
    }
}

int query(int rt,int l,int r,int pos) {
    if(l == r) return Val[rt];
    pushdown(rt);
    int mid = (l + r) >> 1;
    if(pos <= mid) return query(lson,pos);
    else return query(rson,pos);
}

int main() {
    int h,l,r,power,rb;
    while(scanf("%d",&n) != EOF) {
        plank.clear(); rb = -1;
        memset(f,0,sizeof(f));
        memset(lazy,-1,sizeof(lazy));
        for(int i = 0;i < n;i++) {
            scanf("%d%d%d%d",&h,&l,&r,&power);
            plank.PB(Plank(h,l,r,power));
            rb = max(rb,r);
        }
        plank.PB(Plank(0,1,rb,0));
        sort(plank.begin(),plank.end());
        update(1,1,rb,1,rb,0);
        for(int i = 1;i <= n;i++) {
            int xl = query(1,1,rb,plank[i].l),
                xr = query(1,1,rb,plank[i].r);
            f[i] = max(f[xl],f[xr]) + plank[i].power;
            update(1,1,rb,plank[i].l,plank[i].r,i);
        }
        LL ans = f[n] + 100; ans = max(ans,-1LL);
        cout << ans << endl;
    }
    return 0;
}

  

HDU 3016 Man Down 线段树+简单DP

时间: 2024-07-30 14:52:16

HDU 3016 Man Down 线段树+简单DP的相关文章

hdu 3016 Man Down (线段树 + dp)

题目大意: 是男人就下一般层...没什么可以多说的吧. 注意只能垂直下落. 思路分析: 后面求最大值的过程很容易想到是一个dp的过程 . 因为每一个plane 都只能从左边 从右边下两种状态. 然后我们所需要处理的问题就是 ,你如何能快速知道往左边下到哪里,往右边下到哪里. 这就是线段树的预处理. 讲线段按照高度排序. 然后按照高度从小到大加入到树中. 然后去寻找左端点 和 右端点最近覆盖的线段的编号. #include <cstdio> #include <iostream> #

hdu(3016) Man Down(线段树查询更新+dp)

这道题目可以说是游戏的简化版. 题目的大致意思是: 首先我们只有两种板,一种使能量增加,另一种却使能量减少. 最开始人物站在最高层,然后它一开始有100的生命值,它每次下落只能掉到离他最近的木板上去,当然他只能从左端点或者是右端点往下掉. 但是如果没有板满足如下情况的话,那么他就掉到最底下去了,如果此时他的能量小于等于0的话,那么他就会死亡,那么则输出-1:否则输出他所能获得能量的最大值. 现在的任务是叫你输出最大所能获得最大能量值. 思路: 1)我们要找到当前区间的分别从左右端点下去离他最近的

HDU 3016 Man Down(线段树)

HDU 3016 Man Down 题目链接 题意:是男人就下100层的游戏的简单版,每次仅仅能从两端下落.求落地最大血量 思路:利用线段树能够处理出每一个线段能来自哪几个线段.然后就是dag最长路了 代码: #include <cstdio> #include <cstring> #include <algorithm> #include <vector> using namespace std; const int N = 100005; int n;

hdu 3016 Man Down(线段树)

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.

HDU 4902 Nice boat(线段树)

HDU Nice boat 题目链接 题意:给定一个序列,两种操作,把一段变成x,把一段每个数字,如果他大于x,就变成他和x的gcd,求变换完后,最后的序列. 思路:线段树,每个结点多一个cover表示该位置以下区间是否数字全相同,然后每次延迟操作,最后输出的时候单点查询即可 代码: #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N = 1

hdu 2795 Billboard(线段树)

Billboard Time Limit: 20000/8000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 10890    Accepted Submission(s): 4827 Problem Description At the entrance to the university, there is a huge rectangular billboard of

HDU 3954 Level up 线段树

---NotOnlySuccess 出的题--- 看了题之后觉得和HDU 4027有点像,给的K很小,只有10,目测只要有人升级的时候直接更新到叶子节点就ok了.不过不同于HDU 4027 的是,那题每一次更新都相当于这题的一次升级操作,这题里面可能会出现一次操作之后没有升级和出现升级两种情况,一时半会没了思路. 无奈去搜题解,发现我只要维护一个区间当中距离升级最近的人所需要的基础升级经验,即不算等级加成的裸的升级经验,如果在一次涨经验之后,出现当前区间当中有人会升级,直接将每一个要升级的人更新

多校训练hdu --Nice boat(线段树,都是泪)

Nice boat Time Limit: 30000/15000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 47 Accepted Submission(s): 10 Problem Description There is an old country and the king fell in love with a devil. The devil always ask

HDU 3308 LCIS(线段树)

Problem Description Given n integers.You have two operations:U A B: replace the Ath number by B. (index counting from 0)Q A B: output the length of the longest consecutive increasing subsequence (LCIS) in [a, b]. Input T in the first line, indicating