zoukankan      html  css  js  c++  java
  • 线段覆盖

    【题目描述】

    在一个数轴上有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<=Right)
        {
            Mid=(Left+Right)>>1;
            if (i[Mid].R>i[t].L)
              Right=Mid-1;
            else
              Left=Mid+1;
        }
        if (i[Right].R<=i[t].L)
          return Right;
        else
          return Left; //无合法情况时,Right会一直下降,直至为-1。
    }
    int main() //普通的线段覆盖DP加了个二分查找。
    {
        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;
    }
  • 相关阅读:
    浏览器的渲染与小优化
    css3 贝塞尔曲线理解
    mac下配置汇编环境
    报错 net::ERR_CONTENT_LENGTH_MISMATCH 200 (OK)
    vue中使用iframe,加载完成的onload事件偶尔不触发
    nrm的使用
    js原生实现元素跟随鼠标拖动
    webpack多页面打包笔记
    关于React的组件优化笔记
    React生成器
  • 原文地址:https://www.cnblogs.com/Ackermann/p/5933036.html
Copyright © 2011-2022 走看看