zoukankan      html  css  js  c++  java
  • [USACO09FEB]庙会班车Fair Shuttle

    题目描述

    逛逛集市,兑兑奖品,看看节目对农夫约翰来说不算什么,可是他的奶牛们非常缺乏锻炼——如果要逛完一整天的集市,他们一定会筋疲力尽的。所以为了让奶牛们也能愉快地逛集市,约翰准备让奶牛们在集市上以车代步。但是,约翰木有钱,他租来的班车只能在集市上沿直线跑一次,而且只能停靠N(1 ≤N≤20000)个地点(所有地点都以1到N之间的一个数字来表示)。现在奶牛们分成K(1≤K≤50000)个小组,第i 组有Mi(1 ≤Mi≤N)头奶牛,他们希望从Si跑到Ti(1 ≤Si<Ti≤N)。

    由于班车容量有限,可能载不下所有想乘车的奶牛们,此时也允许小里的一部分奶牛分开乘坐班车。约翰经过调查得知班车的容量是C(1≤C≤100),请你帮助约翰计划一个尽可能满足更多奶牛愿望的方案。

    输入输出格式

    输入格式:

    【输入】

    第一行:包括三个整数:K,N和C,彼此用空格隔开。

    第二行到K+1行:在第i+1行,将会告诉你第i组奶牛的信息:Si,Ei和Mi,彼

    此用空格隔开。

    输出格式:

    【输出】

    第一行:可以坐班车的奶牛的最大头数。

    输入输出样例

    输入样例#1:
    8 15 3
    1 5 2
    13 14 1
    5 8 3
    8 14 2
    14 15 1
    9 12 1
    12 15 2
    4 6 1
    
    输出样例#1:
    10
    

    说明

    【样例说明】

    班车可以把2头奶牛从1送到5,3头奶牛从5送到8,2头奶牛从8送到14,1头

    奶牛从9送到12,1头奶牛从13送到14,1头奶牛从14送到15。

    题解:

    线段树

    根据贪心思想,按结束点从小到大排序,对于每组牛,只要满足加入x只后区间最大值小于c即可。

    用线段树维护区间最大值,区间加,记得修改和询问时终点要减一(终点已下车)

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 struct Node
     7 {
     8     int s,t,m;
     9 }a[50001];
    10 int lazy[80001],c1[80001],k,n,c,ans;
    11 bool cmp(Node a,Node b)
    12 {
    13     return (a.t<b.t||(a.t==b.t&&a.s>b.s));
    14 }
    15 void pushdown(int rt)
    16 {
    17     if (lazy[rt])
    18     {
    19         c1[rt*2]+=lazy[rt];
    20         lazy[rt*2]+=lazy[rt];
    21         c1[rt*2+1]+=lazy[rt];
    22         lazy[rt*2+1]+=lazy[rt];
    23         lazy[rt]=0;
    24     }
    25 }
    26 int query(int rt,int l,int r,int L,int R)
    27 {
    28     if (l>=L&&r<=R)
    29     {
    30         return c1[rt];
    31     }
    32     pushdown(rt);
    33      int mid=(l+r)/2;
    34      int s=0;
    35      if (L<=mid) s=max(s,query(rt*2,l,mid,L,R));
    36      if (R>mid) s=max(s,query(rt*2+1,mid+1,r,L,R));
    37      return s;
    38 }
    39 void add(int rt,int l,int r,int L,int R,int d)
    40 {
    41     if (l>=L&&r<=R)
    42     {
    43         c1[rt]+=d;
    44         lazy[rt]+=d;
    45         return;
    46     }
    47     pushdown(rt);
    48     int mid=(l+r)/2;
    49     if (L<=mid) add(rt*2,l,mid,L,R,d);
    50      if (R>mid) add(rt*2+1,mid+1,r,L,R,d);
    51      c1[rt]=max(c1[rt*2],c1[rt*2+1]);
    52 }
    53 int main()
    54 {int i,j;
    55     cin>>k>>n>>c;
    56      for (i=1;i<=k;i++)
    57      {
    58          scanf("%d%d%d",&a[i].s,&a[i].t,&a[i].m);
    59          a[i].t--;
    60      }
    61      sort(a+1,a+k+1,cmp);
    62      for (i=1;i<=k;i++)
    63      {
    64          int x=min(a[i].m,c-query(1,1,n,a[i].s,a[i].t));
    65           add(1,1,n,a[i].s,a[i].t,x);
    66           ans+=x;
    67      }
    68      cout<<ans;
    69 }
  • 相关阅读:
    Java学习路线:day1 Java语言概述
    Java学习路线:day5 Java基本语法(下)2
    Java学习路线:day4 Java基本语法(下)
    Python笔记_第四篇_高阶编程_GUI编程之Tkinter_2.控件类
    Python笔记_第四篇_高阶编程_GUI编程之Tkinter_1.使用Python进行GUI编程的概述
    Python笔记_第三篇_面向对象_9.Python中的"get"和"set"方法(@property和@.setter)
    Python笔记_第三篇_面向对象_8.对象属性和类属性及其动态添加属性和方法
    Python笔记_第三篇_面向对象_7.多态
    Python笔记_第三篇_面向对象_6.继承(单继承和多继承)
    Python笔记_第三篇_面向对象_5.一个关于类的实例(人开枪射击子弹)
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/7182302.html
Copyright © 2011-2022 走看看