问题:你有n元钱,有两种牛奶,一种价值a元,一种价值b元,但回瓶子可以得到c元,两种牛奶不存在差异,问最多买多少瓶牛奶。
我们想让买的牛奶数最多,那每瓶消耗的钱应该是最少的,所以我们就挑每种实际价格小的购买。
但我们还得注意一些小问题:
1.假如第二种牛奶每瓶单价较小,但n < b,那我们只能买第一种。
2.因为c < d,如果已经满足上面的条件,那么n就一直在减少,终会出现上面的情况,我们就不能直接用n / (d - c)。
3.如果上面的问题已经解决,那最后n < b一定成立,但n < a不一定成立,所以我们就要再选几瓶第一种牛奶。
4.上面发生的条件都是a > b-c,若a <= b-c,那么我们就可以直接选a,可以直接除。
对于问题2,注释有点写不下就放在这里。
我们可以先选出一个b,然后每次都是先加c,再减b,那么我们就可以直接用除法。
对于n( = n-b)每次先加c再减b,到 n+c < b时,n < b - c。
最后把第一个瓶子的回收费c加上,那么n还满足 n < b的。
看注释
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main() {
ll n, a, b, c, t, ans = 0;
scanf("%lld%lld%lld%lld", &n, &a, &b, &c);
if(a > b-c) {
if(n >= b) {
//问题2的解决
n -= b, ans++;
ans += n / (b - c);
n %= (b - c);
n += c;
}
//问题3 + 问题1
ans += n/a;
}
//问题4
else ans += n/a;
printf("%lld", ans);
return 0;
}
下面是我第一遍写的代码,用的是循环,Tle了,可以借鉴一下。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main() {
ll n, a, b, c, t, ans = 0;
scanf("%lld%lld%lld%lld", &n, &a, &b, &c);
if(a > b-c) {
while(n >= b) {
t = n/b;
n %= b;
ans += t;
n += t*c;//我在这还想ll * ll会不会爆,没想到Tle了。
}
ans += n/a;
}
else ans += n/a;
printf("%lld", ans);
return 0;
}