有什么算法,能在设定的总金额,规定次数内发放完总金额

比如总金额100,规定兑换50份,每份的金额在1-2.5之间(可以等于界限值),怎么在50次发放完100块钱?

阅读 3.4k
4 个回答

1 首先 平均分配,100/50 = 2,存入数组 [100]
2 循环若干次(次数 50次以上),随机数组一项
向下可减去额度是 add = x-1, 向上可增加额度是 sub = 2.5-x
随机确定是 向上还是向下,取减去 0-sub 或 /增加额度 0-add 随机值,调整值记为 delta
随机取数组另一项,执行反向操作,增加 或 减去 delta,若超出范围,则 保留差值,继续调整,直到 delta = 0

const 红包分配 = (总额, 总数, 范围) => {
    const [ 最小值, 最大值 ] = 范围
    let 分配结果 = []
    let 已分配金额 = 0
    let 已分配总数 = 0
    while (已分配总数 < 总数 - 1) {
        let 分配金额
        do {
            分配金额 = 最小值 + Math.random() *  (最大值 - 最小值)
            const 剩余平均 = (总额 - 已分配金额 - 分配金额) / (总数 - 已分配总数 - 1)
            if (剩余平均 > 最小值 * 1.01 && 剩余平均 < 最大值 * .99) {
                break;
            }
        } while (true)

        分配结果.push(分配金额)
        已分配金额 += 分配金额
        已分配总数++
    }
    分配结果.push(总额 - 已分配金额)
    return 分配结果
}

console.log(红包分配(100, 50, [1, 2.5]).map((n, i) => (i && i % 5 === 0 ? '\n' : '') + n.toFixed(2)).join(', '))

image.png

弄了个,有时有点超边界,大多数情况下随得比较平均

    // java
    static double START = 1.5d;
    static double END = 2.5d;

    public static void main(String[] args) {~~~~
        double amount = 100d;
        int n = 50;
        double start = START;
        double end = END;
        double remain = amount;
        double total = 0;
        List<Double> list = new ArrayList<>();
        
        for (int i = 0; i < n - 1; i++) {
            double d = RandomUtils.nextDouble(start, end);
            remain -= d;
            total += d;
            System.out.println(d);
            list.add(d);
            double ar = remain / (50d - i - 1);

            start = Math.max(ar - 0.5d, START);
            end = Math.min(ar + 0.5d, END);
        }

        System.out.println(remain);
        total += remain;
        list.add(remain);
        
        System.out.println(list.size());
        System.out.println(total);
    }

image.png

新手上路,请多包涵

这不就是个中学应用题嘛:)
我先想想。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题