腾讯,秋招算法笔试,第三题:杂货店冰淇淋个数

小明开了个店,冰淇淋有 n 个配料, 店里每个配料的 原材料 数量为 wi ,每个 原材料在商店的价格为 vi, 小明有 m 元钱, 问 可以最多做多少冰淇淋

第一种方法  暴力求解  AC 40%
if __name__ == "__main__":
    n, m = [int(x) for x in input().strip().split(' ')]
    w = [int(x) for x in input().strip().split(' ')]
    v = [int(x) for x in input().strip().split(' ')]
    cnt = min(w)
    for i in range(n):
        w[i] -= cnt
    while m > 0:
        for i in range(n):
            if w[i] == 0:
                m -= v[i]
            else:
                w[i] -= 1
        cnt += 1
    if m == 0:
        print(cnt)
    else: print(cnt-1)

第二种方法,二分查找
def cost(num, w, v):
    price = 0
    for i in range(n):
        if w[i] > num:
            continue
        price += v[i]*(num-w[i])
    return price

if __name__ == "__main__":
    n, m = [int(x) for x in input().strip().split(' ')]
    w = [int(x) for x in input().strip().split(' ')]
    v = [int(x) for x in input().strip().split(' ')]
    l = min(w)
    r = 1 + m//sum(v) + max(w)
    while l < r:
        mid = (l + r + 1) >> 1
        if cost(mid, w, v) < m:
            l = mid
        else:
            r = mid-1
    print(l)
刚才是写程序 右边界的初始值 有问题, 所以 样例通过70%
现在把代码 改了下 应该通过 100%

#腾讯##笔试题目#
全部评论
楼主,能说下思路嘛
点赞 回复 分享
发布于 2019-08-18 10:03
背包问题
点赞 回复 分享
发布于 2019-08-18 10:05
楼主能说下思路么
点赞 回复 分享
发布于 2019-08-18 10:13
我也是二分法,但只过了20% #include<bits/stdc++.h> using namespace std; int n, v[110], idx = 1; long long m, w[110],min_w, ans; bool check(long long wi){     int q = 0;     for(int i=1;i<=n;i++){         q += (wi - w[i])*v[i];         if (q>m)return false;     }     return true; } int main(){     scanf("%d%lld", &n, &m);     for (int i = 1;i <= n;i++){         scanf("%lld", &w[i]);         if(i == 1)min_w = w[i];         else {             if (w[i] < min_w){                 min_w = w[i];                 idx = i;             }         }     }     ans = min_w;     for (int i = 1;i <= n;i++) w[i] -= min_w;     for (int i = 1;i <= n;i++)scanf("%d", &v[i]);     long long l = 0, r = (long long)(m/v[idx]), mid;     while(l<r){         mid = (l+r)/2;         if(check(mid)) l = mid;         else r = mid - 1;     }     printf("%lld\n", ans + l);     return 0; }
点赞 回复 分享
发布于 2019-08-18 10:42
这个没有这么复杂
点赞 回复 分享
发布于 2019-08-18 10:44
我想问一下,你的右边界值为什么这么设置? r = 1 + m//sum(v) + max(w)
点赞 回复 分享
发布于 2019-08-18 10:57
少了一种情况,钱足够多,做max(w)还有剩的钱
点赞 回复 分享
发布于 2019-08-18 10:59
while循环里,m应该还需要更新吧?
点赞 回复 分享
发布于 2019-08-18 17:20

相关推荐

02-05 08:18
四川大学 Java
在思考的熊熊很讨厌吃香菜:不是,我门头沟学院呢?这都没排上?
点赞 评论 收藏
分享
评论
2
13
分享

创作者周榜

更多
牛客网
牛客企业服务