51nod 1548 欧姆诺姆和糖果 分情况枚举

第一篇博客测试MarkDown和LeTex
Description
一天,欧姆诺诺姆来到了朋友家里,他发现了许多糖果。有蓝色和红色两种。他知道每颗红色糖果重Wr克,每颗蓝色糖果重Wb克。吃一颗蓝色糖果会给他带来Hb的欢乐值,吃一颗红色糖果会给他带来Hr的欢乐值。欧姆诺姆最多只能吃C克的糖果,而且每一颗糖果不能只吃一半。现在他想通过吃蓝色和红色的糖果来获得最大的欢乐值。
样例解释:每一种糖果吃两颗即可。

Input
单组测试数据。输入占一行有四个整数C,Hr,Hb,Wr,Wb (1≤C,Hr,Hb,Wr,Wb≤10^9).

Output
输出最大可能获得的欢乐值。

Input示例
10 3 5 2 3

Output示例
16

题解:
为保证最大利润,如果知道了一种物品的个数x,那么另一个物品的个数y是可以算出来的,即\(y=\lfloor\frac{C-x*Wb}{Wr}\rfloor\)

当存在一种物品\(W>\sqrt{C}\)时,这种物品的数量不会超过\(\sqrt{C}\)个,所以就可以枚举这种物品的个数,取最大值。

\(Wb,Wr\leq\sqrt{C}\)时,\(Wb*Wr\leq C\)。我们选Wb和r和Wr个b的体积是一样的,都是Wb * Wr,但是收益一个是Wb * Hr,一个是Wr * Hb。所以收益较小的那种物品假设为r,那么r的数量不会超过Wb个,否则可以整体换成b。所以r的数量\(<Wb\leq \sqrt{C}\)

最终复杂度\(O(\sqrt{C})\)

code

#include<stdio.h>
#include<iostream>
#include<cmath>
using namespace std;
typedef long long LL;
LL C,Hr,Hb,Wr,Wb;
int main(){
	scanf("%lld%lld%lld%lld%lld",&C,&Hr,&Hb,&Wr,&Wb);
	LL Sqr=(LL)sqrt(double(C));
	if(Wr>Sqr) swap(Hr,Hb),swap(Wr,Wb);
	LL k=0,ans=0;
	if(Wb<=Sqr){
		if(Wr*Hb>Wb*Hr) swap(Hr,Hb),swap(Wr,Wb);
		for(LL i=0,d=0;i<=Sqr;++i,d+=Wb)
		    ans=max(ans,i*Hb+((C-d)/Wr)*Hr);
	}
	else for(LL d=0,i=0;d<=C;++i,d+=Wb)
	    ans=max(ans,i*Hb+((C-d)/Wr)*Hr);
	printf("%lld",ans);
	return 0;
}
原文地址:https://www.cnblogs.com/kito/p/6999937.html