(背包)[USACO10JAN]Cheese Towers S

博客详细分析了USACO竞赛中的一道题目,涉及完全背包算法的应用。由于洛谷题目的翻译不明确,博主通过代码解释和注释清晰阐述了解题思路。

一、算法分析

完全背包套一个枚举,洛谷的题目翻译好像没说清是完全背包。详解看代码及注释。

二、代码及注释

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#define v first
#define h second
using namespace std;
//如果有大奶酪,则大奶酪必然在塔顶,因为大奶酪会影响塔中的所有奶酪
//且塔顶的其它大奶酪是不是大奶酪都无所谓了,因为压缩只算一次
//可以分成两种情况,第一种是塔顶没有大奶酪,则从所有小奶酪里面进行完全背包
//第二种是塔顶有大奶酪,则枚举放在塔顶的大奶酪,其余的奶酪对其高度取到原来的五分之四,然后进行完全背包
const int N=105;
const int M=1050;
int n,t,k;
typedef pair<int,int> PII;
PII w[N];
int big[N];
int cnt;                                    //记录所有的大奶酪
int f[M];
int ans1,ans2;
int main(){
    
    cin>>n>>t>>k;
    for(int i=1;i<=n;i++){
        scanf("%d%d",&w[i].v,&w[i].h);
        if(w[i].h>=k) big[++cnt]=i;
    }
    
    //第一种情况,不选大奶酪
    for(int i=1;i<=n;i++){
        if(w[i].h>=k) continue;
        for(int j=w[i].h;j<=t;j++){
            f[j]=max(f[j],f[j-w[i].h]+w[i].v);
        }
    }
    ans1=f[t];
    
    
    //第二种情况,枚举最上面的大奶酪
    for(int k=1;k<=cnt;k++){
        memset(f,0,sizeof(f));
        int p=big[k];
        int m=t-w[p].h;                     //去掉大奶酪之后的剩余高度
        if(m<0) continue;
        for(int i=1;i<=n;i++){
            for(int j=w[i].h*4/5;j<=m;j++){ //一定要注意这里的j初始值也要一并乘以4/5,调试了好久这个问题
                f[j]=max(f[j],f[j-w[i].h*4/5]+w[i].v);
            }
        }
        ans2=max(ans2,f[m]+w[p].v);
    }
    
    
    
    cout<<max(ans1,ans2);
    
    return 0;
    
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值