二分求解决方案

**

B - Hamburgers

**
做三明治需要面包、香肠和奶酪,用B代表,S代表香肠,C代表奶酪,不同的三明治所含的这三种原料不同。杜老板的厨房现在有有nb块面包,ns块香肠和nc块奶酪。除此之外,这三种原料在附近的商店都有,价格是一片面包pb元,一片香肠ps元,一片奶酪pc元。杜老板有钱,他准备去买。他最多能做多少汉堡?你可以假设它不会破坏或切掉面包、香肠或奶酪的任何一块。除此之外,店里每种原料的数量都是无限量的。

Input
输入的第一行包含一个非空字符串,它描述了三明治的配方。字符串的长度不超过100,字符串只包含字母’B’(英文大写B), ‘S’(英文大写S)和’C’(英文大写C)。

第二行包含三个整数nb, ns, nc(1≤nb, ns, nc≤100)——杜老板的厨房里的面包、香肠、奶酪的块数。

第三行包含三个整数pb, ps, pc(1≤pb, ps, pc≤100)——商店里一片面包、香肠、奶酪的价格。

最后,第四行包含整数r(1≤r≤10^12)——杜老板现在有多少钱。

注意,请不要用% lld,最好使用cin、cout流或%I64d说明符。
Output
打印杜老板能做的三明治的最大数量。如果他做不成,打印0。

Examples
Input
BBBSSC
6 4 1
1 2 3
4
Output
2

Input
BBC
1 10 1
1 10 1
21
Output
7

Input
BSC
1 1 1
1 1 3
1000000000000
Output
200000000001

**思路 **利用二分,寻找能做三文治的最大数量
代码有详细解析;

#include<iostream>
#include<cstring>
using namespace std;
typedef long long ll;
char s[110];
ll have[5];
ll need[5];
ll money[5],cnt;
int sovle(ll mid)
{
	ll i,sum=cnt;
	for(i=1;i<=3;i++){//枚举每一种配料
		ll t=have[i]-need[i]*mid;//t表示的是要做mid个三文治,现在需要购买的数量 
		if(t<0) sum+=t*money[i];//如果t<0,则证明have不够,需要购买,购买后sum钱数也自然减少 
		if(sum<0) return 0;//如果 钱数<0了,证明这个方案不成立 
	}
	return 1;//整个购买过程都成立,返回1
}
int main()
{
	ll i;
	while(~scanf(" %s",s)){
		memset(have,0,sizeof(have));
		for(i=0;i<strlen(s);i++){//统计三文治的配方,需要的各种数量 
			if(s[i]=='B'){
				need[1]++; 
			}
			else if(s[i]=='S'){
				need[2]++;
			}
			else need[3]++;
		}
		
		for(i=1;i<=3;i++){
			scanf("%I64d",&have[i]);//have表示本来已经拥有的 
		}
		for(int i=1;i<=3;i++)
            scanf("%I64d",&money[i]);//每种食材的单价 
        
		ll l=0,r=10e12,ans=0,mid;//一般来说 l,r的区域范围要包括解决办法在内,r可以大一点 
		scanf("%I64d",&cnt);//拥有的钱 
		while(l<=r){
			mid=(l+r)/2;//mid表示要做多少个三文治 
			if(sovle(mid)==1){
				ans=mid;//更新最优方案 
				l=mid+1;//这个方案成立,l+1,尝试做更多三文治 
			}
			else r=mid-1;//不能解决,则缩小mid,所以r=mid-1 
		}
		cout <<ans<< endl;
}
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值