hdu 3016(线段树+dp)
来源:互联网 发布:淘宝一般星期几流量高 编辑:程序博客网 时间:2024/06/10 09:14
看了别人的博客才AC的。
这题以dp为主要,线段树打辅助,线段树为后面的dp做铺垫!
首先想怎么dp:
1、建立一个结构体
struct plank{
int h , l , r, value;//木板本身的属性,高度、左端点、右端点、值
int vl , vr; //从木板左边跳到vl木板 , 右边跳到vr木板
plank(int H = 0, int L = 0, int R = 0,int V = 0){
h = H , l = L , r = R ,value = V;
}
};
2、把木板按照高度从低到高排序
3、状态转移方程,很好理解,看看就能懂
for(int i = N;i >=1;i--){
dp[p[i].vl] = max(dp[p[i].vl] ,dp[i]+p[p[i].vl].value);
dp[p[i].vr] = max(dp[p[i].vr] ,dp[i]+p[p[i].vr].value);
}
然后,想求出plank中的vl、vr,就用线段树!
1、
struct tree{
int l , r , id;//id指l到r区间,第几块木板,初始化为0,我们木板的编号从1开始,0表示地板;
}a[4*maxn];
4
5 2 4 100 //plank4
4 1 3 100 //plank3
3 3 4 100 //plank2
2 1 4 100 //plank1
#include <iostream>#include <cstdio>#include <algorithm>using namespace std;const int maxn = 100010;struct plank{int h , l , r, value;int vl , vr;plank(int H = 0, int L = 0, int R = 0, int V = 0){h = H , l = L , r = R , value = V;}}p[maxn];struct tree{int l , r , id;}a[4*maxn];int N , dp[maxn];bool cmp(plank p1 , plank p2){return p1.h < p2.h;}void pushdown(int k){if(a[k].l != a[k].r){a[2*k].id = a[k].id;a[2*k+1].id = a[k].id;a[k].id = -1;}}void build(int l , int r , int k){a[k].l = l;a[k].r = r;a[k].id = 0;if(l != r){int mid = (l+r)/2;build(l , mid , 2*k);build(mid+1 , r , 2*k+1);}}int query(int k , int x){if(a[k].id != -1){return a[k].id;}else{int mid = (a[k].l+a[k].r)/2;if(mid >= x){return query(2*k , x);}else{return query(2*k+1 , x);}}}void add(int l , int r , int k, int id){if(l <= a[k].l && a[k].r <= r){a[k].id = id;}else{if(a[k].id != -1){pushdown(k);}int mid = (a[k].l+a[k].r)/2;if(mid >= r){add(l , r , 2*k , id);}else if(mid < l){add(l , r , 2*k+1 , id);}else{add(l , mid , 2*k , id);add(mid+1 , r , 2*k+1 , id);}}}void initial(){for(int i = 0;i < maxn;i++){dp[i] = 0;p[i].value = 0;}}void readcase(){int h , xl , xr , v , M_r = 0;for(int i = 1;i <= N;i++){scanf("%d%d%d%d" , &h , &xl , &xr , &v);p[i] = plank(h , xl ,xr , v);M_r = max(M_r , xr);}build(1 , M_r , 1);}void computing(){sort(p+1 , p+N+1 , cmp);for(int i = 1;i <= N;i++){p[i].vl = query(1 , p[i].l);p[i].vr = query(1 , p[i].r);add(p[i].l , p[i].r , 1 , i);//cout << i << ":" << p[i].vl << " " << p[i].vr << endl;}dp[N] = p[N].value+100;for(int i = N;i >= 1;i--){dp[p[i].vl] = max(dp[p[i].vl] , dp[i]+p[p[i].vl].value);dp[p[i].vr] = max(dp[p[i].vr] , dp[i]+p[p[i].vr].value);//cout << dp[i] << ":" << p[i].vl <<"=" << dp[p[i].vl] << " " <<p[i].vr <<"=" << dp[p[i].vr]<<endl;}if(dp[0]>0){cout << dp[0] << endl;}else{cout << -1 << endl;}}int main(){while(cin >> N){initial();readcase();computing();}return 0;}
- hdu 3016(线段树+dp)
- hdu 3016(线段树+dp)
- hdu 3016 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 线段树+简单dp
- hdu 3016 Man Down 线段树+dp
- hdu 3016 Man Down (线段树 + dp)
- 【HDU】3016 Man Down 线段树DP
- HDU 3016 线段树单点更新+DP
- Hdu 3016 Man Down【线段树+Dp】
- HDU-3016:Man Down(线段树+DP)
- hdu-4991(dp+线段树)
- hdu 6155(线段树+dp+矩阵)
- HDU 3607 线段树+DP
- C/C++ 编码规范
- hibernate之HQL之full join和笛卡儿积
- FCKEditor 中文字体添加与中文字体无效的解决方法
- c++中多线程编程是不是线程数越多越好?
- Interface
- hdu 3016(线段树+dp)
- Ajax 在IE 10下不能正常工作一例
- 利用lua_pcall()的errfunc参数调试LUA程序
- 拥抱变化
- 计算机基础
- Shell中同时读多个文件
- linux 下用ecipse 作用oracle 的客户端
- #ifndef、#define、#endif
- Hibernate tutorial with Eclipse