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;
    }
  • 相关阅读:
    Ansys Maxwell2——二维电磁场理论和有限元基础
    Ansys Maxwell在工程电磁场中的应用1——二维分析技术
    第四章 栈
    第三章 链表
    第二章 队列
    第三章 操作系统用户界面总结
    第一章 逻辑结构与物理结构
    Linux-Mint的一些配置经验
    docker安装zookeeper的使用说明
    SpringCloud初体验-使用Eureka进行服务注册和发现
  • 原文地址:https://www.cnblogs.com/Ackermann/p/5933036.html
Copyright © 2011-2022 走看看