【微众银行2020实习生笔试】有n位小朋友去小明家里拜年,小明准备了m份礼物。小明想把所有礼物平均分给每个小朋友,每个小朋友得到相同个数的礼物。但是m未必能被n整除,小明可以使用以下两种操作任意多次(

题目描述:有n位小朋友去小明家里拜年,小明准备了m份礼物。小明想把所有礼物平均分给每个小朋友,每个小朋友得到相同个数的礼物。但是m未必能被n整除,小明可以使用以下两种操作任意多次(两种操作可以同时使用)。

1、 给其中一个小朋友发红包,收到红包的小朋友会离开小明家。每个红包需要花费a元。

2、 购买一个新礼物,每个礼物价值为b元。

问小明最少花费多少元,才能使得所有礼物可以被剩下的小朋友平分。

输入
第一行输入四个整数n,m,a,b(1≤n,m,a,b≤100)。

输出
输出最少花费。

样例输入
7 5 10 100

样例输出
20

提示
输入样例2
2 2 10 10

输出样例2
0

输入样例3
3 1 10 10

输出样例3
20

样例解释
样例一发两个红包。样例二不需要任何操作。样例三买两个新礼物,或者发两个红包,或者发一个红包买一个新礼物。

解析

作者:Galliano、
链接:https://www.nowcoder.com/discuss/403152?type=all&order=time&pos=&page=1
来源:牛客网



/**
 * 微众 第 1 题,最小花费问题
 */
public static void main1(String[] args) {
    Scanner sc = new Scanner(System.in);
    int n = sc.nextInt(); // n个小朋友
    int m = sc.nextInt(); // m份礼物
    int a = sc.nextInt(); // 每个红包的花费
    int b = sc.nextInt(); // 每个礼物的价值
    sc.close();
    System.out.println(minCost(n, m, a, b));
}
private static int minCost(int n, int m, int a, int b) {
    if (n > m) { // 当人数大于礼物数时
        // 此时对于 (人数和礼物数) 的差值,要么发红包,要么买新礼物,且 红包数+新礼物数 = n - m
        // 此时当然是选 单个红包和礼物中较便宜的那个。
        return (n - m) * Math.min(a, b);
 
    } else if (m % n == 0){ // 当可以完全均分时,不需要额外花钱
        return 0;
 
    } else { // 其他情况为:当人数小于礼物数时,且不能完全均分时
        // 列出线性规划方程
        // n:总客人数, m:总礼物数
        // x:离开多少人,y:买多少礼物,k的目的是:让礼物能完全均分,k必须是自然数
        // 方程1:k * (n - x) = m + y
        // 方程2:minCost = x * a + y * b,求能使minCost最小的 x 和 y。
        int res = Integer.MAX_VALUE;
 
        // redPacketNum代表发几个红包,最多只需要发 n-1 个红包
        for (int redPacketNum = 1; redPacketNum < n; redPacketNum++) {
            // 求出当发 redPacketNum 个红包时,需要买的礼物数 buyGiftNum
            if (m % (n - redPacketNum) == 0) {
                res = Math.min(res , redPacketNum * a);
            } else {
                int buyGiftNum = (m / (n - redPacketNum) + 1) * (n - redPacketNum) - m;
                res = Math.min(res , redPacketNum * a + buyGiftNum * b);
            }
        }
        return res;
    }
}
 
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值