zoukankan      html  css  js  c++  java
  • 线段覆盖(序列动态规划+离散化)

    线段覆盖

    题目描述:
    数轴上有n条线段,线段的两端都是整数坐标,坐标范围在0~10^18,每条线段有一个价值,请从n条线段中挑出若干条线段,使得这些线段两两不覆盖(端点可以重合)且线段价值之和最大。
    输入描述:
    第一行一个整数n,表示有多少条线段。
    接下来n行每行三个整数, ai bi ci,分别代表第i条线段的左端点ai,右端点bi(保证左端点<右端点)和价值ci。
    输出描述:
    输出能够获得的最大价值
    样例输入:
    3
    1 2 1
    2 3 2
    1 3 4
    样例输出:
    4
    数据范围及提示:
    n <= 1000000
    0<=ai,bi<=10^18
    0<=ci<=10^9
    数据输出建议使用long long类型(Pascal为int64或者qword类型)

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #define in long long
    using namespace std;
    const in maxn=1000010;
    struct node
    {
        in l;
        in r;
        in v;
        bool operator < (node tmp)const
        {
            return r<tmp.r;
        }
    }e[maxn];
    in n,tot,a[maxn*2],f[maxn*2];
    in init()
    {
        in x=0,f=1;char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    int main()
    {
        n=init();
        for(in i=1;i<=n;i++)
        {
            e[i].l=init();e[i].r=init();e[i].v=init();
            a[++tot]=e[i].l,a[++tot]=e[i].r;
        }
        sort(a+1,a+tot+1);
        in sum=unique(a+1,a+tot+1)-(a+1);
        for(in i=1;i<=n;i++)
        {
            in tmp=lower_bound(a+1,a+sum+1,e[i].l)-a;
            e[i].l=tmp;
            tmp=lower_bound(a+1,a+sum+1,e[i].r)-a;
            e[i].r=tmp;
        }
        sort(e+1,e+n+1);
        int now=1;
        for(in i=1;i<=sum;i++)
        {
            f[i]=f[i-1];
            while(e[now].r==i)
            {
                f[i]=max(f[i],f[e[now].l]+e[now].v);
                now++;
            }
        }
        cout<<f[sum];
        return 0;
    }
  • 相关阅读:
    并不对劲的网络流
    并不对劲的[noi2006]网络收费
    并不对劲的spoj1812
    48.孩子们的游戏(圆圈中最后剩下的数)
    47.扑克牌顺子
    46.翻转单词顺序
    45.左旋转字符串
    44.和为S的两个数字
    43.和为S的连续正数序列
    42.数组中只出现一次的数字
  • 原文地址:https://www.cnblogs.com/cax1165/p/6070928.html
Copyright © 2011-2022 走看看