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

    题目描述

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

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

    输入输出格式

    输入格式:

    【输入】

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

    第二行到(K+1)行:在第(i+1)行,将会告诉你第(i)组奶牛的信息:(S_i)(E_i)(M_i),彼

    此用空格隔开。

    输出格式:

    【输出】

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

    输入输出样例

    输入样例#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)

    思路:
    题意是给你几堆奶牛,每个奶牛都有想去的地方,给你一个汽车,汽车有一个容量和固定的行走路线,询问最多能搭载的奶牛的数量。

    我们来考虑一种贪心的思想,按右端点从小到大排一遍序,为什么呢?后面说,然后对排好序的每堆奶牛依次进行遍历,如果当前有空位,空位大于这堆奶牛的数量,那就全上去,不然的话,就能上去几个就上去几个。这样下来的话,结果一定是最优的,其正确性不难证明,因为刚开始我们对每堆奶牛要到的地方从小到大排了序(即终点),那么每个位置最多只有一次奶牛上车,而且这些奶牛来自同一群,所以我们对每堆奶牛分别进行考虑即可,这就是为什么要按右端点排序的原因。贪心过程中,要维护最大值。因为要算最少的空位子,下面给出两种代码:

    自己整理的题解

    1、纯贪心&贪心:

    #include<cstdio>
    #include<algorithm>
    #include<cctype>
    #define maxn 50007
    using namespace std;
    int ans,n,m,k,w[maxn];
    inline int qread() {
      char c=getchar();int num=0,f=1;
      for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
      for(;isdigit(c);c=getchar()) num=num*10+c-'0';
      return num*f;
    }
    struct node {
      int u,v,c;
    }e[maxn];
    const int inf=0x7fffffff;
    inline bool cmp(node a, node b) {
      if(a.v!=b.v) return a.v<b.v;
      return a.u<b.u;
    }
    int main() {
      k=qread(),n=qread(),m=qread();
      for(int i=1;i<=k;++i) e[i].u=qread(),e[i].v=qread(),e[i].c=qread();
      sort(e+1,e+1+k,cmp);
      for(int i=1;i<=k;++i) {
        if(w[e[i].u]>=m) continue;
        int minn=inf;
        for(int j=e[i].u;j<=e[i].v;++j) {
          minn=min(m-w[j],minn);
          if(minn<=0) break;
        }
        if(minn>0) {
          if(minn>=e[i].c) { 
            for(int j=e[i].u;j<e[i].v;++j)
              w[j]+=e[i].c;
            ans+=e[i].c;
          }
          else {
            for(int j=e[i].u;j<e[i].v;++j)
              w[j]+=minn;
            ans+=minn;
          }
        }
      }
      printf("%d
    ",ans);
      return 0;
    }
    

    2、线段树&贪心&排序:

    #include<cstdio>
    #include<algorithm>
    #include<cctype>
    #define maxn 20007
    #define ls rt<<1
    #define rs rt<<1|1
    using namespace std;
    const int inf=0x7fffffff;
    int n,k,m,maxx[maxn<<2],lazy[maxn<<2],zrj,w[50007];
    inline int qread() {
      char c=getchar();int num=0,f=1;
      for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
      for(;isdigit(c);c=getchar()) num=num*10+c-'0';
      return num*f;
    }
    struct node {
      int u,v,c;
    }e[50007];
    inline bool cmp(node a, node b) {
      if(a.v!=b.v) return a.v<b.v;
      return a.u<b.u;
    }
    inline void pushup(int rt) {
      maxx[rt]=max(maxx[ls],maxx[rs]);
    }
    inline void pushdown(int rt) {
      if(lazy[rt]) {
        maxx[ls]+=lazy[rt],lazy[ls]+=lazy[rt];
        maxx[rs]+=lazy[rt],lazy[rs]+=lazy[rt];
        lazy[rt]=0;
      }
    }
    void modify(int rt, int l, int r, int L, int R, int val) {
      if(L>r||R<l) return;
      if(L<=l&&r<=R) {
        lazy[rt]+=val,maxx[rt]+=val;
        return;
      }
      int mid=(l+r)>>1;
      pushdown(rt);
      modify(ls,l,mid,L,R,val),modify(rs,mid+1,r,L,R,val);
      pushup(rt);
    }
    int cmax(int rt, int l, int r, int L, int R) {
      if(L>r||R<l) return -inf;
      if(L<=l&&r<=R) return maxx[rt];
      int mid=(l+r)>>1,ans=-inf;
      pushdown(rt);
      if(L<=mid) ans=max(ans,cmax(ls,l,mid,L,R));
      if(R>mid) ans=max(ans,cmax(rs,mid+1,r,L,R));
      return ans;
    }
    int main() {
      k=qread(),n=qread(),m=qread();
      for(int i=1;i<=k;++i) e[i].u=qread(),e[i].v=qread(),e[i].c=qread();
      sort(e+1,e+1+k,cmp);
      for(int i=1;i<=k;++i) {
        int p=cmax(1,1,n,e[i].u,e[i].v-1);
        int minn=min(m-p,e[i].c);
        zrj+=minn,w[i]+=minn;
        modify(1,1,n,e[i].u,e[i].v-1,w[i]);
      }
      printf("%d
    ",zrj);
      return 0;
    }
    
  • 相关阅读:
    我的游戏学习日志54———类型游戏策划(1)—动作游戏(1)
    我的游戏学习日志53——游戏游戏策划—小结
    IE8下Extjs报缺少':'符号错误
    Extjs 兼容IE8常见问题及解决方法
    程序员如何提升自己
    extjs layout 最灵活的页面布局样式
    如何运用军事战略建立更好的习惯
    Ext之页面多次请求问题 (下拉框发送无关请求)
    计算机网络通信那些事
    Java基础
  • 原文地址:https://www.cnblogs.com/grcyh/p/10226333.html
Copyright © 2011-2022 走看看