zoukankan      html  css  js  c++  java
  • P1607 [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


    把车看成很多教室 每个时间点有C个教室 然后往里面装牛就可以了 贪心思路很简单

    朴素算法超时了: 7000ms
    #include<bits/stdc++.h>
    using namespace std;
    //input by bxd
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);--i)
    #define RI(n) scanf("%d",&(n))
    #define RII(n,m) scanf("%d%d",&n,&m)
    #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
    #define RS(s) scanf("%s",s);
    #define ll long long
    #define pb push_back
    #define inf 0x3f3f3f3f
    #define CLR(A,v)  memset(A,v,sizeof A)
    //////////////////////////////////
    const int N=1e5+6;
    
    struct node
    {
        int l,r,num;
    }s[N];
    int sum[N],n,m,C;
    
    bool cmp(node a,node b)
    {
        return a.r==b.r?a.l<b.l:a.r<b.r;
    }
    int main()
    {
        RIII(n,m,C);
        rep(i,1,n)RIII(s[i].l,s[i].r,s[i].num);
        sort(s+1,s+1+n,cmp);
    
        int ans=0;
    
        rep(i,1,n)
        {
            int minn=inf;
            rep(j,s[i].l,s[i].r-1)
            minn=min(C-sum[j],minn);
            minn=min(minn,s[i].num);
    
            ans+=minn;
            rep(j,s[i].l,s[i].r-1)sum[j]+=minn;
        }
        cout<<ans;
    
        return 0;
    }
    View Code

    加两条剪枝就能过 250ms

    #include<bits/stdc++.h>
    using namespace std;
    //input by bxd
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);--i)
    #define RI(n) scanf("%d",&(n))
    #define RII(n,m) scanf("%d%d",&n,&m)
    #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
    #define RS(s) scanf("%s",s);
    #define ll long long
    #define pb push_back
    #define inf 0x3f3f3f3f
    #define CLR(A,v)  memset(A,v,sizeof A)
    //////////////////////////////////
    const int N=50007;
    
    struct node
    {
        int l,r,num;
    }s[N];
    int sum[N],n,m,C;
    
    bool cmp(node a,node b)
    {
        return a.r==b.r?a.l<b.l:a.r<b.r;
    }
    int main()
    {
        RIII(n,m,C);
        rep(i,1,n)RIII(s[i].l,s[i].r,s[i].num);
        sort(s+1,s+1+n,cmp);
    
        int ans=0;
    
        rep(i,1,n)
        {   
            if(sum[ s[i].l ]>=C)continue;//剪枝
            int minn=inf;
            rep(j,s[i].l,s[i].r-1)
            {
                minn=min(C-sum[j],minn);
                if(minn==0)break;
            }
            if(minn==0)continue;//剪枝
            
            minn=min(minn,s[i].num);
    
            ans+=minn;
            rep(j,s[i].l,s[i].r-1)sum[j]+=minn;
        }
        cout<<ans;
    
        return 0;
    }
    View Code

     也可以用线段树来做  维护一下最大值就可以了







  • 相关阅读:
    GO语言面向对象06---面向对象练习01
    GO语言面向对象05---接口的多态
    GO语言面向对象04---接口的继承
    GO语言面向对象03---接口与断言
    GO语言面向对象02---继承
    Go语言练习---判断闰年以及根据现在的秒数求现在的年月日
    [操作系统] 线程管理
    [操作系统] 进程的状态
    [操作系统] 进程控制块
    关于这次计算机设计大赛
  • 原文地址:https://www.cnblogs.com/bxd123/p/10982027.html
Copyright © 2011-2022 走看看