2013 Asia Reginal Contest Problem D --- Chocolate (DP + 二分)

链接:http://acm.hrbust.edu.cn/index.php?m=ProblemSet&a=showProblem&problem_id=1788

Description

Ikki 喜欢吃巧克力,暑假里她得到了一个很长的巧克力。Ikki有好多的朋友,她准备和她们一起分享这块巧克力。

巧克力可以看成是由无数个连续的区间段组成的,区间段的标号从1开始,依次为1,2,3...,而且每个区间段的巧克力都有特别的味道哦。Ikki的朋友们每人都挑了一段自己喜欢的巧克力,但是每段巧克力只能给一个人,Ikki应该如何分配巧克力才能得到最大的满意度?

Input
多组测试数据,处理到文件结束,对于每组数据:

第一行:输入一个整数N表示Ikki的朋友数量(1 <= N <= 100000)

接下来的n行,每行三个整数s, e, p,s表示该朋友喜欢的区间段起点,e表示终点,p表示如果该朋友得到该段巧克力后增加的满意度(注意只有该朋友得到完整的从s到e这段巧克力,才能增加相应的满意度)。

(1 <= s <= e <= 1000000) (1 <= p <= 1000)

Output

对于每组测试数据输出一个整数表示Ikki的到的最大满意度,每组输出占一行。

Sample Input

2
1 2 1
2 4 2
2
1 2 1
3 4 2

Sample Output

2
3


分析:

“今年暑假不AC”的数据强化版。
可以先按照巧克力左端点的位置从小到大排序,再重后向前遍历,用二分找到左端点在现在这个人要的巧克力右端点
右边的左端点最小的巧克力。
dp[0][i] 表示从i 到n这些人中,分给第i个人想要的巧克力得到的最大满意度
dp[1][i] 表示从i+1到n这些人中得到的最大满意度
那么如果存在t左端点在此巧克力的右边
dp[0][i] = val[i] + max(dp[0][t], dp[1][t]) 否则 dp[0][i] = val[i]
dp[1][i] = max(dp[0][i+1], dp[i][i+1]);

代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <set>
#include <ctype.h>
#include <algorithm>
#define MAXN 100005
#define RST(N)memset(N, 0, sizeof(N))
using namespace std;

typedef struct Node_
{
    int st, en, val;
}Node;

Node q[MAXN];
int dp[2][MAXN], n, tmp;

int cmp(const void *a, const void *b)
{
    return (*(Node *)a).st - (*(Node *)b).st;
}

int max(int x, int y) { return x > y ? x : y; }

int bin_search(int ti, int x)
{
    int res = -1;
    int low = x, high = n-1, mid;
    while (low <= high) {
        mid = (low + high) >> 1;
        if (q[mid].st > ti) {
            res = mid;
            high = mid - 1;
        }else low = mid + 1;
    }
    return res;
}

int main()
{
    while(~scanf("%d", &n)) {
        for(int i=0; i<n; i++) scanf("%d %d %d", &q[i].st, &q[i].en, &q[i].val);
        qsort(q, n, sizeof(Node), cmp);
        dp[0][n] = dp[1][n] = 0;
        for(int i=n-1; i>=0; i--) {
            tmp = bin_search(q[i].en, i+1);
            if(tmp != -1) {
                dp[0][i] = q[i].val + (dp[0][tmp] > dp[1][tmp] ? dp[0][tmp] : dp[1][tmp]);
            }else {
                dp[0][i] = q[i].val;
            }
            dp[1][i] = max(dp[0][i+1], dp[1][i+1]);
        }
        printf("%d\n", max(dp[1][0],dp[0][0]));
    }
    return 0;
}


你可能感兴趣的:(dp,二分,2013亚洲区赛题)