!hdu 4091--贪心、枚举--(思维)

本文深入探讨了一个涉及珠宝体积和价值最大化的复杂问题,通过将问题分解为贪心算法和枚举算法的结合应用,实现了解决方案。文章详细分析了初始误解和尝试后的策略调整,最终通过LCM(最小公倍数)概念和条件判断,实现了高效的算法设计。关键在于理解问题本质,并灵活运用多种算法技术。

题意:有一个容量为n的箱子,有两种珠宝,占的体积和价值分别是s1,v1,s2,v2,求能装下的最大的价值总量。

分析:刚开始以为是背包问题,但其实没那么简单;后来分情况讨论还是不行;后来又暴力枚举,当然是超时了。正确做法是有一部分是用背包的贪心,另一部分用枚举!现在就是看哪一部分用贪心。

看别人的题解是:L = LCM(s1,s2),可是知道大于L的部分就用价值比高的,所以n%L的部分枚举,其余部分贪心,不过这样可能得到的还不是最优解,所以n%L+L的部分枚举,这样就可以了,具体原因我还没想明白。继续思考!

注意:枚举的时候用max(s1,s2),不然会超时。

总之这道题非常好,思维很重要。

代码:

#include<iostream>
#include<cmath>
using namespace std;
long long t,n,s1,s2,v1,v2,ans,mx,tmp,l;
int gcd(long long a,long long b)
{
	if(a<b) swap(a,b);
	if(a%b==0) return b;
	return gcd(b,a%b);
}
int main()
{
	cin>>t;
	for(int i=1;i<=t;i++){
		mx=-1;
		cin>>n>>s1>>v1>>s2>>v2;
		l=s1*s2/gcd(s1,s2);
		int p=n/l,q=n%l;
		if(p){
			p--;
			q+=l;
		}
		if(s1*v2<s2*v1) ans=p*l/s1*v1;
		else ans=p*l/s2*v2;
		if(s1<s2){
			swap(s1,s2);
			swap(v1,v2);
		}
		for(int j=0;j<=q/s1;j++){
			tmp=v1*j+v2*((q-j*s1)/s2);
			if(mx<tmp) mx=tmp;
		}
		ans+=mx;
		cout<<"Case #"<<i<<": "<<ans<<endl;
	}
}


评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值