zoukankan      html  css  js  c++  java
  • Cogs 1435. [USACO NOV]金发姑娘和N头牛

    1435. [USACO NOV]金发姑娘和N头牛

    ★★☆   输入文件:milktemp.in   输出文件:milktemp.out   简单对比
    时间限制:1 s   内存限制:256 MB

    【题目描述】

    你可能已经听说了金发姑娘和3只熊的经典故事。

    鲜为人知的是,金发姑娘最终经营了一个农场。在她的农场,她有一个谷仓含N头奶牛(1<=N <= 20000)。不幸的是,她的奶牛对温度相当敏感。

    第i头奶牛必须在指定的温度范围内A(i)..B(i)才感觉舒适;(0<=A(i)<=B(i)<= 1,000,000,000)。如果金发姑娘在谷仓放置一个温控器;如果温度T<A(i),牛会太冷,并将产生x单位牛奶。如果她把恒温器调到(A(i)<=T<=B(i))这个范围内,那么牛会感到舒适,并将产生Y单位牛奶。如果她把恒温器调到温度T>B(i),牛会感觉很热,并将产生的Z单位牛奶。正如预期的那样,Y的值总是大于X和Z。

    给定的X,Y,和Z,以及每个牛的温度的最佳范围,如果金发姑娘设置谷仓的温控器最佳,请计算金发姑娘得到牛奶的最大数量,已知X,Y和Z都是整数,范围0..1000。温控器可以设置为任意整数的值。

    【输入格式】

    第1行:四个用空格隔开的整数:N X Y Z。

    第2行..1 + N:行1+i包含两个用空格隔开的整数:A(i)和B(i)。

    【输出格式】

    1行:金发姑娘最多可以获得的牛奶,当她在谷仓的最佳温度设定。

    【样例输入】

    4 7 9 6 5 8 3 4 13 20 7 10

    【样例输出】

    31

    【提示】

    在农场里有4头奶牛,温度范围5..8,3..4,13..20,10..7。一个寒冷的奶牛生产7单位的牛奶,一个舒适的奶牛生产9个单位的牛奶,一个热牛生产6单位牛奶。

    【数据规模】

    50%的测试数据:n<=5

    其余50%的测试数据:10000<n<=20000.

    【来源】

    USACO 2013 November Contest, Bronze

    translate by cqw

    data from cstdio

    /*
        这道题利用差分的思想,
        无非只有三个区间: 
           1: [1, A(i)-1] 在c[0]的位置加上x;
           2:  [ A(i), B(i)] 在c[A(i)] 的位置上加上y-x;
           3:  [B(i)+1, n ] 在B(i)+1的位置上加上z-y;
        这样,查询某个温度的前缀和,就是奶牛在这个温度产生的牛奶量;
        
        但是, A(i)与B(i)的范围太大, N 又那么小, 所以我们不难想到用离散化;
        观察以上区间,其实只有三个点有用,0, A(i), B(i)+1, ;这三个点完全可以代替这三个区间;
        所以我们只需保留A(i),B(i)的相对位置就行, 就是不用知道具体多大, 比他大的还在他后面,比他小的还在他前面;
        这就是所谓的离散化;(本蒟蒻的见解)
        因为每个A(i),B(i)+1, 要加的值是一样的,所以A(i), B(i)的顺序打乱后并不影响结果,这样就可以把他们排序,以便离散;
    */
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    #define maxn 50010
    int a[maxn],b[maxn],c[maxn];
    struct node{
        int l,r;
    }A[maxn];
    int h[maxn],B[maxn],tot,to;
    int bs(int x){
        int l=1,r=tot,res=0;
        while(l<=r){
            int mid=(l+r)>>1;
            if(h[mid]>=x)res=mid,r=mid-1;
            else l=mid+1;
        }
        return res;
    }
    int main(){
        freopen("milktemp.in","r",stdin);freopen("milktemp.out","w",stdout);
        int n,x,y,z;
        scanf("%d%d%d%d",&n,&x,&y,&z);
        for(int i=1;i<=n;i++){
            scanf("%d%d",&A[i].l,&A[i].r);
            B[++to]=A[i].l;
            B[++to]=A[i].r;
        }
        sort(B+1,B+to+1);
        h[++tot]=B[1];
        for(int i=2;i<=to;i++)
            if(B[i]!=B[i-1])h[++tot]=B[i];
        for(int i=1;i<=n;i++){
            int u=bs(A[i].l);
            a[u]--;b[u]++;
            u=bs(A[i].r);
            b[u+1]--;c[u+1]++;
        }
        int xnum=n,ynum=0,znum=0;
        int ans=0;
        for(int i=1;i<=tot;i++){
            xnum+=a[i];
            ynum+=b[i];
            znum+=c[i];
            ans=max(ans,xnum*x+ynum*y+znum*z);
        }
        printf("%d",ans);
        return 0;
    }
  • 相关阅读:
    Leetcode(337)-打家劫舍III
    Leetcode(213)-打家劫舍II
    Leetcode(198)-打家劫舍
    Leetcode(32)-最长有效括号
    计数排序
    智能指针
    C++中的explicit
    Leetcode(878)-第 N 个神奇数字
    Leetcode(877)-石子游戏
    C++的memset
  • 原文地址:https://www.cnblogs.com/thmyl/p/7694918.html
Copyright © 2011-2022 走看看