HDU 3016 Man Down

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[N].h = 0, plank[N].x1 = 0, plank[N].x2 = M, plank[N].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[N] > 0 ? f[N] : -1);
}
int main()
{
    while(scanf("%d", &N) == 1)
    {
        init();
        solve();
    }
    return 0;
}
原文地址:https://www.cnblogs.com/staginner/p/2445845.html