您的位置:首页 > 其它

HDU 3016 Man Down

2012-04-13 15:16 218 查看
HDU_3016

为了处理起来方便,我们可以先将plank对h排个序,最后补一个(0,100000)的value为0的plank。我们可以用f[i]表示跳到第i个plank时value和的最大值进行dp,每次在寻找可以由哪些plank落到第i个plank上时可以借助线段树。

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define MAXD 100010
int N, M, f[MAXD], num[4 * MAXD], col[MAXD];
struct Plank
{
int h, x1, x2, value;
}plank[MAXD];
int cmp(const void *_p, const void *_q)
{
Plank *p = (Plank *)_p, *q = (Plank *)_q;
return p->h > q->h ? -1 : 1;
}
void init()
{
int i, j, k;
M = 100000;
for(i = 0; i < N; i ++)
scanf("%d%d%d%d", &plank[i].h, &plank[i].x1, &plank[i].x2, &plank[i].value);
qsort(plank, N, sizeof(plank[0]), cmp);
plank
.h = 0, plank
.x1 = 0, plank
.x2 = M, plank
.value = 0;
}
void build(int cur, int x, int y)
{
int mid = (x + y) >> 1, ls = cur << 1, rs = (cur << 1) | 1;
num[cur] = 0;
if(x == y)
return ;
build(ls, x, mid);
build(rs, mid + 1, y);
}
void update(int cur)
{
num[cur] = num[cur << 1] + num[(cur << 1) | 1];
}
void Insert(int cur, int x, int y, int k, int c)
{
int mid = (x + y) >> 1, ls = cur << 1, rs = (cur << 1) | 1;
if(x == y)
{
num[cur] = 1;
col[x] = c;
return ;
}
if(k <= mid)
Insert(ls, x, mid, k, c);
else
Insert(rs, mid + 1, y, k, c);
update(cur);
}
void Erase(int cur, int x, int y, int &ans)
{
int mid = (x + y) >> 1, ls = cur << 1, rs = (cur << 1) | 1;
if(x == y)
{
if(f[col[x]] > ans)
ans = f[col[x]];
num[cur] = 0;
return ;
}
if(num[ls])
Erase(ls, x, mid, ans);
if(num[rs])
Erase(rs, mid + 1, y, ans);
update(cur);
}
void refresh(int cur, int x, int y, int s, int t, int &ans)
{
int mid = (x + y) >> 1, ls = cur << 1, rs = (cur << 1) | 1;
if(x >= s && y <= t)
{
if(num[cur])
Erase(cur, x, y, ans);
return ;
}
if(mid >= s)
refresh(ls, x, mid, s, t, ans);
if(mid + 1 <= t)
refresh(rs, mid + 1, y, s, t, ans);
update(cur);
}
void solve()
{
int i, j, k, ans;
build(1, 0, M);
f[0] = 100 + plank[0].value;
if(f[0] > 0)
Insert(1, 0, M, plank[0].x1, 0), Insert(1, 0, M, plank[0].x2, 0);
for(i = 1; i <= N; i ++)
{
ans = -plank[i].value;
refresh(1, 0, M, plank[i].x1, plank[i].x2, ans);
f[i] = ans + plank[i].value;
if(f[i] > 0)
Insert(1, 0, M, plank[i].x1, i), Insert(1, 0, M, plank[i].x2, i);
}
printf("%d\n", f
> 0 ? f
: -1);
}
int main()
{
while(scanf("%d", &N) == 1)
{
init();
solve();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: