• 面包


    面包
    (cheese.pas/c/cpp)
    【问题描述】
    Farmer John 有 N 种不同类型的面包(编号 1~N),每种面包的数量无限多。 Farmer John
    想用这些面包堆成一个高度不超过 T 的面包塔。第 i 种面包的价值是 V_i,高度是 H_i,而且
    高度是 5 的倍数。已知一个常量 K,如果高度≥K,我们称它为“大面包”,大面包会把堆在
    它下面的所有面包都压扁(即使下面同样有大面包)。面包被压扁后价值不会改变,但高度
    变成了原来的 4/5。由于所有面包原来高度都是 5 的倍数,所以压扁后的高度还是整数。某
    块面包被压扁一次后不会再被压扁第二次,也就是说每块面包要么被压扁要么不被压扁。现
    在的问题是: Farmer John 堆成一个高度不超过 T(1≤T≤l000)的面包塔,能获得最大的价值
    是多少?
    例如: T=53, K=25。以下有三种不同类型的面包,数量无限:
    Type Value Height
    1 100 25
    2 20 5
    3 40 10
    FJ 能够堆出下面的面包塔:
    Type Height Value
    Top -> [1] 25 100
    [2] 4 20 <一被第[1]块面包压扁了
    [3] 8 40 <一被第[1]块面包压扁了
    [3] 8 40 <一被第[1]块面包压扁了
    Bottom -> [3] 8 40 <一被第[1]块面包压扁了
    由于最上层的面包高度是 25≥K,所以把它下面所有的面包压扁,面包塔总高度是:
    25+4+8+8+8 刚好不超过 T,所以是合法的,面包塔的总价值是: 100+20+40+40+40=240。这
    也是最优方案:
    【输入格式】
    第 1 行:三个整数: N, T, K。
    第 2~N+1 行:第 i+1 行有两个整数: v_i、 H_i,表示第 i 种面包的信息。
    【输出格式】
    一行:能堆出来的最大价值。
    【输入样例】
    3 53 25
    100 25
    20 5
    40 10
    【输出样例】
    240
    【数据规模】
    对于 30%的数据:1≤N≤15; 1≤T≤100;
    对于 70%的数据:1≤N≤70; 1≤T≤500;
    对于 100%的数据:1≤N≤100; 1≤T≤1,000; 1≤V_i≤1,000,000; 5≤H_i≤T; 1≤K≤T;


    这题是个完全背包,这是毋庸置疑的,但是因为有4/5,整个题目的难度就提升了。
    此题的做法是先将高度比k小的面包取出,做一次完全背包。将其记录为ans1。
    然后将所有面包高度的4/5取出,做一遍完全背包,最后再在上面取出高度比k大的
    面包,再做再顶部。将其记录为ans2。
    输出max(ans1,ans2)即可。

    #include<bits/stdc++.h>
    #define C c=getchar()
    using namespace std;
    int i,j,k,n,m,tot,ans,t;
    int f[1005],h[105],v[105];
    int read(){
        char c;int x;while(C,c<'0'||c>'9');x=c-'0';
        while(C,c>='0'&&c<='9') x=x*10+c-'0';return x;
    }
    int maxn(int a,int b){return a>b?a:b;}
    int minn(int a,int b){return a<b?a:b;}
    int main()
    {
        freopen("cheese.in","r",stdin);freopen("cheese.out","w",stdout);
        n=read();t=read();k=read();
        for(int i=1;i<=n;i++){
            v[i]=read(); h[i]=read();
        }
        for(int i=1;i<=n;i++)
         if(h[i]<k) for(int j=h[i];j<=t;j++) f[j]=maxn(f[j],f[j-h[i]]+v[i]);
        for(int i=0;i<=t;i++) ans=maxn(ans,f[i]);
        for(int i=1;i<=n;i++)
         for(int j=h[i]*4/5;j<=t;j++) 
            f[j]=maxn(f[j],f[j-h[i]*4/5]+v[i]);
        for(int i=1;i<=n;i++)
         if(h[i]>=k) for(int j=h[i];j<=t;j++) ans=maxn(ans,f[j-h[i]]+v[i]);
        printf("%d",ans);
        return 0;
    }
  • 相关阅读:
    [翻译]WP 平衡球游戏开发教程(一) 初识 XNA Farseer Magic
    Windows Phone7开发必备资源汇总
    WP7的XML操作详解:读取,过滤以及数据绑定
    为listbox的SelectedItem加入翻转动画(附源码)
    [翻译]WP 平衡球游戏开发教程(二) 在XNA 渲染Farseer物理对象
    wp7创建动画闪屏,启动画面所有知识深入详解(附源码)
    [翻译] wp7游戏 源码加分析
    Wp7 list中列表项多样化的解决方案CustomDataTemplateSelector(附源码)
    [翻译]WP 平衡球游戏开发教程(四) 深入了解windowsphone7 游戏底层原理
    [翻译]WP 平衡球游戏开发教程(三) DebugDraw(XNA渲染)
  • 原文地址:https://www.cnblogs.com/stevensonson/p/7612208.html
Copyright © 2020-2023  润新知