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

来源:互联网 发布:蒋媛是现代版知画 编辑:程序博客网 时间:2024/05/14 14:02

链接: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;}


0 0