• 轻轨【线段树】【贪心】


    题目大意:

    N个站点的轻轨站,有一个容量为C的列车起点在1号站点,终点在N号站点,有K组牛群,每组数量为M[i],行程起点和终点分别为S[i]E[i]。请你计算最多有多少头牛可以搭乘轻轨。


    思路:

    线段树+贪心

    其实这道题直接用贪心就能过,编程复杂度也简单,但是就是比较难理解。
    这道题如果我们将每群牛的起点和终点看成起始时间和终止时间,C看做会场场数,那么这道题就很像 活动安排 了。
    每次查询起点和终点的之间的最大值,将牛尽量放进车上,并标记这个区间新添加了这么多牛,中间所有添加的牛的数量即为答案。

    这里写图片描述


    代码:

    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    int n,m,k,sum,ans,sum2;
    
    struct node1
    {
        int l,r,max,lazy;
    }tree[300001];
    
    struct node2
    {
        int l,r,num;
    }a[300001];
    
    void make(int x)
    {
        if (tree[x].r==tree[x].l) return;
        int mid=(tree[x].l+tree[x].r)/2;
        tree[x*2].l=tree[x].l;
        tree[x*2].r=mid;
        tree[x*2+1].l=mid+1;
        tree[x*2+1].r=tree[x].r;
        make(x*2);
        make(x*2+1);
    }
    
    bool cmp(node2 x,node2 y)
    {
        return x.r<y.r||(x.r==y.r&&x.l<y.l);
    }
    
    void pushdown(int x)
    {
        if (tree[x].lazy)
        {
            tree[x*2].lazy+=tree[x].lazy;
            tree[x*2+1].lazy+=tree[x].lazy;
            tree[x*2].max+=tree[x].lazy;
            tree[x*2+1].max+=tree[x].lazy;
            tree[x].lazy=0;
        }
    }
    
    int find(int x,int l,int r)
    {
        if (tree[x].l>r||tree[x].r<l) return 0;
        if (tree[x].l>=l&&tree[x].l<=r) return tree[x].max;
        pushdown(x);
        int lmax=find(x*2,l,r);
        int rmax=find(x*2+1,l,r);
        tree[x].max=max(tree[x*2].max,tree[x*2+1].max);
        int maxn=max(lmax,rmax);
        return maxn;
    }
    
    void add(int x,int l,int r,int k)
    {
        if (tree[x].l>r||tree[x].r<l) return;
        if (tree[x].l>=l&&tree[x].r<=r) 
        {
            tree[x].max+=k;
            tree[x].lazy+=k;
            return;
        }
        pushdown(x);
        add(x*2,l,r,k);
        add(x*2+1,l,r,k);
        tree[x].max=max(tree[x*2].max,tree[x*2+1].max);
    }
    
    int main()
    {
        scanf("%d%d%d",&m,&n,&k);
        tree[1].l=1;
        tree[1].r=n;
        make(1);
        for (int i=1;i<=m;i++)
        {
            scanf("%d%d%d",&a[i].l,&a[i].r,&a[i].num);
        }
        sort(a+1,a+1+m,cmp);
        for (int i=1;i<=m;i++)
        {
            sum=find(1,a[i].l,a[i].r);
            if (k<sum) continue;
            sum2=min(a[i].num,k-sum);
            ans+=sum2;
            add(1,a[i].l,a[i].r-1,sum2);
        }
        return printf("%d\n",ans)&0;
    }
  • 相关阅读:
    .net log4dll的使用
    Myslq 5.7安装
    接口和抽象类有什么区别
    monkey测试
    JDK、Jmeter、Android环境变量配置
    聊天室
    tushrea知识笔记
    爬取图片
    python gui之tkinter事件处理
    ttk.Treeview
  • 原文地址:https://www.cnblogs.com/hello-tomorrow/p/9313033.html
Copyright © 2020-2023  润新知