zoukankan      html  css  js  c++  java
  • 洛谷 P2979 [USACO10JAN]奶酪塔Cheese Towers

    题目描述

    Farmer John wants to save some blocks of his cows' delicious Wisconsin cheese varieties in his cellar for the coming winter. He has room for one tower of cheese in his cellar, and that tower's height can be at most T (1 <= T <= 1,000). The cows have provided him with a virtually unlimited number of blocks of each kind of N (1 <= N <= 100) different types of cheese (conveniently numbered 1..N). He'd like to store (subject to the constraints of height) the most

    valuable set of blocks he possibly can. The cows will sell the rest to support the orphan calves association.

    Each block of the i-th type of cheese has some value V_i (1 <= V_i <= 1,000,000) and some height H_i (5 <= H_i <= T), which is always a multiple of 5.

    Cheese compresses. A block of cheese that has height greater than or equal to K (1 <= K <= T) is considered 'large' and will crush any and all of the cheese blocks (even other large ones) located below it in the tower. A crushed block of cheese doesn't lose any value, but its height reduces to just 4/5 of its old height. Because the height of a block of cheese is always a multiple of 5, the height of a crushed block of cheese will always be an integer. A block of cheese is either crushed or not crushed; having multiple large blocks above it does not crush it more. Only tall blocks of cheese crush other blocks; aggregate height of a tower does not affect whether a block is crushed or not.

    What is the total value of the best cheese tower FJ can construct?

    Consider, for example, a cheese tower whose maximum height can be 53 to be build from three types of cheese blocks. Large blocks are those that are greater than or equal to 25. Below is a chart of the values and heights of the various cheese blocks he stacks:

    Type Value Height

    1 100 25

    2 20 5

    3 40 10

    FJ constructs the following tower: 
    Type Height Value 
    top -> [1]   25    100 
    [2]    4     20   <- crushed by [1] above 
    [3]    8     40   <- crushed by [1] above 
    [3]    8     40   <- crushed by [1] above 
    bottom -> [3]    8     40   <- crushed by [1] above 

    The topmost cheese block is so large that the blocks below it are crushed. The total height is:

    25 + 4 + 8 + 8 + 8 = 53 
    The total height does not exceed 53 and thus is 'legal'. The total value is: 
    100 + 20 + 40 + 40 + 40 = 240. 
    This is the best tower for this particular set of cheese blocks. 
    要建一个奶酪塔,高度最大为T。他有N块奶酪。第i块高度为Hi(一定是5的倍数),价值为Vi。一块高度>=K的奶酪被称为大奶酪,一个奶酪如果在它上方有大奶酪(多
    块只算一次),它的高度就会变成原来的4/5.。 很显然John想让他的奶酪他价值和最大。求这个最大值。

    输入输出格式

    输入格式:

     

    • Line 1: Three space-separated integers: N, T, and K

    • Lines 2..N+1: Line i+1 contains two space separated integers: V_i and H_i

     

    输出格式:

     

    • Line 1: The value of the best tower FJ can build

     

    输入输出样例

    输入样例#1:
    3 53 25 
    100 25 
    20 5 
    40 10 
    
    输出样例#1:
    240 
    思路:如果没有大奶酪,这个题目可以看成是完全背包来做。但是加上了大奶酪,所以就把状况分开,把大奶酪和没有大奶酪分开来看。
    如果没有大奶酪:f[j][0]=max(f[j][0],f[j-h[i]][0]+v[i]);

    如果某个奶酪上能放大奶酪,即f[j-w[i]*4/5][1]存在解:f[j][1]=max(f[j][1],f[j-w[i]*4/5][1]+v[i]);
    如果没聚到某个奶酪正好是大奶酪:f[j][1]=max(f[j][1],f[(j-w[i])*4/5][0]+v[i]);
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    int T,n,k,tot,f[1100][3];
    struct nond{
        int v,h;
    }nl[1100];
    int cmp(nond x,nond y){
        return x.h>y.h;
    }
    int cmp1(nond x,nond y){
        return x.h<y.h;
    }
    int main(){
        scanf("%d%d%d",&n,&T,&k);
        for(int i=1;i<=n;i++){
            scanf("%d%d",&nl[i].v,&nl[i].h);
            if(nl[i].h>=k)    tot++;
        }
        sort(nl+1,nl+1+n,cmp);
        sort(nl+1,nl+1+tot,cmp1);
        for(int i=1;i<=T;i++)    f[i][1]=-1;
        for(int i=1;i<=n;i++)
            for(int j=nl[i].h;j<=T;j++){
                f[j][0]=max(f[j][0],f[j-nl[i].h][0]+nl[i].v);
                if(f[j-nl[i].h*4/5][1]!=-1)    f[j][1]=max(f[j][1],f[j-nl[i].h*4/5][1]+nl[i].v);
                if(nl[i].h>=k)    f[j][1]=max(f[j][1],f[(j-nl[i].h)*4/5][0]+nl[i].v);
            }    
        cout<<max(f[T][0],f[T][1]);
    }
    细雨斜风作晓寒。淡烟疏柳媚晴滩。入淮清洛渐漫漫。 雪沫乳花浮午盏,蓼茸蒿笋试春盘。人间有味是清欢。
  • 相关阅读:
    AGC012
    AGC010
    AGC010
    AGC010
    AGC010
    BZOJ2120
    python_way,day8 面向对象【多态、成员--字段 方法 属性、成员修饰符、特殊成员、异常处理、设计模式之单例模式、模块:isinstance、issubclass】
    python_way ,day7 面向对象 (初级篇)
    python_way.day7 模块(configparser,xml,shutil,subprocess)、面向对象(上)(创建类,类的构成,函数式编程与面向对象编程的选择,类的继承)
    python_way ,day5 模块,模块3 ,双层装饰器,字符串格式化,生成器,递归,模块倒入,第三方模块倒入,序列化反序列化,日志处理
  • 原文地址:https://www.cnblogs.com/cangT-Tlan/p/7436283.html
Copyright © 2011-2022 走看看