51nod-1548 欧姆诺姆和糖果-枚举


题目来源:  CodeForces
基准时间限制:1 秒 空间限制:131072 KB 分值: 20  难度:3级算法题
 收藏
 关注

一天,欧姆诺诺姆来到了朋友家里,他发现了许多糖果。有蓝色和红色两种。他知道每颗红色糖果重Wr克,每颗蓝色糖果重Wb克。吃一颗蓝色糖果会给他带来Hb的欢乐值,吃一颗红色糖果会给他带来Hr的欢乐值。

欧姆诺姆最多只能吃C克的糖果,而且每一颗糖果不能只吃一半。现在他想通过吃蓝色和红色的糖果来获得最大的欢乐值。

样例解释:每一种糖果吃两颗即可。


Input
单组测试数据。
输入占一行有四个整数C,Hr,Hb,Wr,Wb (1≤C,Hr,Hb,Wr,Wb≤10^9).
Output
输出最大可能获得的欢乐值。
Input示例
样例输入1
10 3 5 2 3
Output示例
样例输出1
16

思路:若直接暴力枚举会超时(C<=10^9),可以考虑优化。

情况一: 若两种糖果中有一种的单个重量大于sqrt(C),则直接枚举其颗数即可。

情况二:若两种糖果的单个重量都小于sqrt(C),即Wr<sqrt(C),Wb<sqrt(C).

假设 Hr/Wr<Hb/Wb ,即 Hr*Wb<Hb*Wr;

若 r糖果有Wb颗,重量 Wr*Wb,欢乐值 Hr*Wb;

若 b糖果有Wr颗,重量Wr*Wb,欢乐值 Hb*Wr;

又 Hr*Wb<Hb*Wr,则 每 Wb颗 r糖果可换成 Wr颗 b糖果所获得的欢乐值更大。

则 可枚举 r糖果的颗数 0->Wb 即可.

code:

#include<iostream>
#include<cmath>
using namespace std;
typedef long long LL;

LL C,h1,h2,w1,w2;
int main()
{
	ios::sync_with_stdio(false);
	while(cin>>C>>h1>>h2>>w1>>w2){
		if(w1<w2){
			swap(h1,h2);	swap(w1,w2);
		}
		LL ans=0;
		if(w1>=sqrt(C)){
			for(int i=0;i<=C/w1;++i)
				ans=max(ans,i*h1+(C-i*w1)/w2*h2);
		}else{
			if((double)h1/w1<(double)h2/w2){
				swap(h1,h2);	swap(w1,w2);
			}
			for(int i=0;i<=w1;++i)
				if(i*w2<=C)
					ans=max(ans,i*h2+(C-i*w2)/w1*h1);
		}
		cout<<ans<<endl;
	}
	return 0;
}

对这两种情况可进行合并:

#include<iostream>
#include<cmath>
using namespace std;
typedef long long LL;


LL C,h1,h2,w1,w2;
int main()
{
	ios::sync_with_stdio(false);
	while(cin>>C>>h1>>h2>>w1>>w2){
		LL ans=0;
		for(int i=0;i<=sqrt(c)+1;++i)
		{
			if(i*w1<=C)
				ans=max(ans,i*h1+(C-i*w1)/w2*h2);
			if(i*w2<=C)
				ans=max(ans,i*h2+(C-i*w2)/w1*h1);
		}
		cout<<ans<<endl;
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值