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;
    }
    
  • 相关阅读:
    Azure HPC Pack Cluster添加辅助节点
    Azure HPC Pack 辅助节点模板配置
    Azure HPC Pack配置管理系列(PART6)
    Windows HPC Pack 2012 R2配置
    Azure HPC Pack 节点提升成域控制器
    Azure HPC Pack VM 节点创建和配置
    Azure HPC Pack 部署必要条件准备
    Azure HPC Pack 基础拓扑概述
    Azure VM 性能计数器配置
    Maven私仓配置
  • 原文地址:https://www.cnblogs.com/grcyh/p/10226333.html
Copyright © 2011-2022 走看看