Codeforces Contest 526 problem C Om Nom and Candies —— 两个物品的无限背包

91 篇文章 0 订阅

A sweet little monster Om Nom loves candies very much. One day he found himself in a rather tricky situation that required him to think a bit in order to enjoy candies the most. Would you succeed with the same task if you were on his place?

在这里插入图片描述
One day, when he came to his friend Evan, Om Nom didn’t find him at home but he found two bags with candies. The first was full of blue candies and the second bag was full of red candies. Om Nom knows that each red candy weighs Wr grams and each blue candy weighs Wb grams. Eating a single red candy gives Om Nom Hr joy units and eating a single blue candy gives Om Nom Hb joy units.

Candies are the most important thing in the world, but on the other hand overeating is not good. Om Nom knows if he eats more than C grams of candies, he will get sick. Om Nom thinks that it isn’t proper to leave candy leftovers, so he can only eat a whole candy. Om Nom is a great mathematician and he quickly determined how many candies of what type he should eat in order to get the maximum number of joy units. Can you repeat his achievement? You can assume that each bag contains more candies that Om Nom can eat.

Input
The single line contains five integers C, Hr, Hb, Wr, Wb (1 ≤ C, Hr, Hb, Wr, Wb ≤ 109).

Output
Print a single integer — the maximum number of joy units that Om Nom can get.

Examples
inputCopy
10 3 5 2 3
outputCopy
16
Note
In the sample test Om Nom can eat two candies of each type and thus get 16 joy units.

题意:

给你背包的容量,两个物品的价值和他们的大小,问你能装的最大价值是多少。

题解:

我们可以假设先用一个物品装满这个背包,之后一个一个拿掉,再放另一个,那么很明显在另一个物品重量/他们两个的重量的gcd的时候会发生些什么:
我们假设背包大小为37,第一个物品的重量为4,价值为3,第二个物品的重量为5,价值为4,。我们假设先都放第二个物品
在这里插入图片描述
那么他们之间的规律就是这样
我们可以发现在一定的时候5减少1个,4就增加的两个,这正好是4/gcd(4,5)的次数,而且在每个循环节的相同位置,他们的价值都是增加或减少一定值的,经过一定的推理,我得出了这样一个结论:
在这里插入图片描述
从上到下是我们第一次假设塞的物品的数量,那么每次循环之后它的值都会改变一定的量,那么画红色圈的地方就一定是最大值,我们枚举一遍即可。那么可能会有人问了,万一这个循环节的长度非常大呢?
不会的,我们假设这两个物品的重量都<1e5,那么循环节的长度就<1e5次,如果>1e5,那么在1e9中循环的次数就<1e4次,所以我们从上到下和从下到上枚举1e5次就一定能够得出答案。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
    ll c,hr,hb,wr,wb;
    scanf("%lld%lld%lld%lld%lld",&c,&hr,&hb,&wr,&wb);
    ll num,ans=0;
    num=c/wr;
    for(int i=1;i<=10000000;i++)
    {
        if(num<0)
            break;
        ans=max(ans,num*hr+(c-num*wr)/wb*hb);
        num--;
    }
    num=c/wb;
    for(int i=1;i<=10000000;i++)
    {
        if(num<0)
            break;
        ans=max(ans,num*hb+(c-num*wb)/wr*hr);
        num--;
    }
    printf("%lld\n",ans);
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值