CodeForces 371C Hamburgers 二分
题意
给你一个做汉堡包的菜单,他们是由B S C
,三种材料做成的,现在我们有一些材料和钱,我们想做最多的汉堡包,请问最多是多少?
解题思路
这里我们开始我们可能会想该怎么买,也就是买的策略是什么,其实我们可以不用去思考这个,理由如下:
假如我们知道最后的结果,我们是不是可以算出来我们要买的东西?答案是肯定的(在钱不浪费的情况下),再加上这个答案是线性单调的,也就是如果答案是m
,那么小于m
的也是一定可以做到的,这样我们就可以使用二分来枚举答案了。
代码实现
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<stack>
#include<queue>
#include<map>
typedef long long ll;
using namespace std;
const double esp=1e-6;
const int inf=0x3f3f3f3f;
const ll llinf=2000000000000;//12个零
const int MAXN=1E6+7;
char recipe[227];
ll need[4], nums[4], price[4], r=0;
bool solve(ll x)
{
ll B=x*need[1], S=x*need[2], C=x*need[3];
ll tmp1=0, tmp2=0, tmp3=0; //每个需要买的材料花费的金额,最好是分开存储。因为有可能会溢出。
if(nums[1] < B)
tmp1= (B - nums[1])*price[1];
if(nums[2] < S)
tmp2= (S - nums[2]) * price[2];
if(nums[3] < C)
tmp3= (C - nums[3]) * price[3];
if(tmp1+tmp2+tmp3 <= r)
return true;
else return false;
}
int main()
{
cin>>recipe;
for(int i=0; i<strlen(recipe); i++)
{
if(recipe[i]=='B')
need[1]++;
else if(recipe[i]=='S')
need[2]++;
else if(recipe[i]=='C')
need[3]++;
}
for(int i=1; i<=3; i++)
cin>>nums[i];
for(int i=1; i<=3; i++)
cin>>price[i];
cin>>r;
ll left=0, right=llinf; //这里的答案最大值不能太大,因为solve函数中由乘法,可能会溢出,很难受。
while(left < right)
{
ll mid=left+(right-left)/2;
if(solve(mid))
left=mid+1;
else right=mid;
}
if(left==0)
cout<<0<<endl;
else cout<<left-1<<endl;
return 0;
}
原文地址:https://www.cnblogs.com/alking1001/p/12255198.html
时间: 2024-10-03 20:15:01