hdu 3016 Man Down(线段树区间更新+dp)
来源:互联网 发布:北方金银分析软件 编辑:程序博客网 时间:2024/05/21 18:41
题意:
是男人就下100层相信很多人都玩过,这题就是简单的模拟这个游戏。
有n 块木板,每块木板有4个属性,高h(h>0),左边界,右边界,以及掉落在它上面,获得多少生命值,一个人从最高的木板开始往下跳,初始时生命值为100,问最后掉落到地面能获得的生命值最多为多少(如果途中生命值为≤0,那么这个人会死去),如果无法跳到地面,输出-1。
解析:
既然只能垂直下落,而且是落在最近的板上,所以其实下落后处于哪个木板是唯一确定的。
所以我们可以逆向考虑,对于任意一块木板,这块木板,可以接到从哪一块木板上面落下来的物体。
这里可以借助线段树。先将木板按h 从小到大排序,初始时,更新线段树里的全部节点为地面的下标,然后往上添加木板的过程就是,单点查询每个木板的左端点和右端点,得到的下标就是当前木板能转移到的其他木板(或者地面),然后将这段区间更新为当前木板的下标。
这样就可以得到每块木板可以落到哪一块木板上了。然后就是利用
dp ,求最大的权值总和,状态转移方程为:
d[line[i].lv]=max(d[line[i].lv],d[i]+line[line[i].lv].val);
d[line[i].rv]=max(d[line[i].rv],d[i]+line[line[i].rv].val);
#include <cstdio>#include <cstring>#include <algorithm>#include <queue>#define ls (o<<1)#define rs (o<<1|1)#define lson ls, L, M#define rson rs, M+1, R#define MID (L + R) >> 1using namespace std;const int N = (int)1e5 + 10;const int INF = 0x3f3f3f3f;int n;struct Line { int h, l, r, val; int lv, rv; bool operator < (const Line& rhs) const { return h < rhs.h; }} line[N];int cov[N<<2];inline void pushDown(int o) { if(cov[o] != -1) { cov[ls] = cov[rs] = cov[o]; cov[o] = -1; }}inline void pushUp(int o) { if(cov[ls] == cov[rs]) cov[o] = cov[ls]; else cov[o] = -1;}void modify(int o, int L, int R, int ql, int qr, int val) { if(ql <= L && R <= qr) { cov[o] = val; return ; } int M = MID; pushDown(o); if(ql <= M) modify(lson, ql, qr, val); if(qr > M) modify(rson, ql, qr, val); pushUp(o);}int query(int o, int L, int R, int pos) { if(L == R) return cov[o]; int M = MID; pushDown(o); if(pos <= M) return query(lson, pos); else return query(rson, pos);}int d[N];int main() { int h, l, r, val; int ql, qr; while(~scanf("%d", &n)) { for(int i = 1; i <= n; i++) { scanf("%d%d%d%d", &h, &l, &r, &val); line[i] = (Line){h, l, r, val}; } sort(line+1, line+n+1); modify(1, 0, N, 0, N, 0); for(int i = 1; i <= n; i++) { line[i].lv = query(1, 0, N, line[i].l); line[i].rv = query(1, 0, N, line[i].r); modify(1, 0, N, line[i].l, line[i].r, i); } memset(d, 0, sizeof(d)); d[n] = 100 + line[n].val; for(int i = n; i > 0; i--){ if(d[i] <= 0) continue; d[line[i].lv]=max(d[line[i].lv], d[i]+line[line[i].lv].val); d[line[i].rv]=max(d[line[i].rv], d[i]+line[line[i].rv].val); } printf("%d\n",d[0] > 0 ? d[0] : -1); } return 0;}
0 0
- hdu 3016 Man Down(线段树区间更新+dp)
- hdu(3016) Man Down(线段树查询更新+dp)
- Man Down(线段树+区间更新+单点查询+dp)
- HDU 3016 Man Down(线段树区间单点查询+DP)
- hdu 3016 Man Down 线段树+dp
- hdu 3016 Man Down (线段树 + dp)
- 【HDU】3016 Man Down 线段树DP
- Hdu 3016 Man Down【线段树+Dp】
- HDU-3016:Man Down(线段树+DP)
- HDU 3016 Man Down (线段树+dp)
- HDU 3016 Man Down(线段树 + DP)
- HDU 3016 Man Down(线段树+离散化+dp)
- hdu-3016-Man Down(线段树)
- hdu 3016 Man Down(简单线段树&简单DP)
- HDOJ3016Man Down(线段树(区间更新,单点查询)+DP)
- hdu 3016 Man Down(线段树)
- hdu 3016 Man Down(线段树)
- HDU 3016 Man Down(线段树)
- JSP四大作用域(转)
- 【Java多线程】-读写锁ReadWriteLock
- LayoutInflate的使用
- android ListView的优化
- Eclipse快捷键 10个最有用的快捷键
- hdu 3016 Man Down(线段树区间更新+dp)
- Get classpath for current running thread
- Java从服务器上获取时间,动态在jsp页面显示
- Python+OpenCV学习(15)---Lucas Kanade 角点光流轨迹跟踪
- 安全通信系统--OpenSSL的安装编译、证书生成
- UINavigationController
- Java中各种线性表的性能分析
- PHP详细学习计划
- Android的隐式意图