码迷,mamicode.com
首页 > 其他好文 > 详细

线段覆盖

时间:2016-10-05 22:19:18      阅读:318      评论:0      收藏:0      [点我收藏+]

标签:

【题目描述】

在一个数轴上有n(n <= 1000000)条线段,每条线段的两端可用整数坐标表示,坐标范围为[0,1018],每条线段都有一个价值Ci(0 <= C<= 109),请从n条线段中选出若干条线段,使得这些线段两两不覆盖(端点可以重合)且线段价值之和最大。

【输入描述】

第一行输入一个整数n,表示有多少条线段;

接下来n行,每行输入三个整数Ai、Bi、Ci,分别代表第i条线段的左端点、右端点(左端点 < 右端点)和价值。

【输出描述】

输出一个数,表示能够获得的最大价值。

【样例输入】

3

1 2 1

2 3 2

1 3 4

【样例输出】

4

#include<cstdio>
#include<algorithm>
using namespace std;
struct Node
{
    unsigned long long L,R,S;
}i[1000001];
unsigned long long f[1000001]={0};
int n;
bool Rule(Node t1,Node t2)
{
    return t1.R<t2.R;
}
int Find(int t)
{
    int Left=0,Right=t-1,Mid=0;
    while (Left+1<Right)
    {
        Mid=(Left+Right)>>1;
        if (i[Mid].R>i[t].L)
          Right=Mid;
        else
          Left=Mid;
    }
    if (i[Right].R<=i[t].L)
      return Right;
    else
      return Left;
}
int main()
{
    scanf("%d",&n);
    for (int a=1;a<=n;a++)
      scanf("%lld%lld%lld",&i[a].L,&i[a].R,&i[a].S);
    sort(i+1,i+n+1,Rule);
    for (int a=1;a<=n;a++)
      f[a]=max(f[a-1],f[Find(a)]+i[a].S);
    printf("%lld",f[n]);
    return 0;
}

 

线段覆盖

标签:

原文地址:http://www.cnblogs.com/Ackermann/p/5933036.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!