二倍均值法实现多人抢红包

  二倍均值法的算法描述:红包剩余金额为m元,剩余人数为n人,则下一个人抢到红包金额的区间为(0, m/n*2)或[0.01, m/n*2-0.01],也就是可能抢到的最大金额为平均金额的二倍。
 
  假设有10个人抢100元,那么第1个人金额区间为(0, 100/10*2),即(0, 20)。假设第1个人抢到10元,那么接下来情况就变成了9个人抢90元,第2个人金额区间为(0, 90/9*2),即(0, 20),以此类推。

<?php
/**
 * 二倍均值法实现多人抢红包
 *
 * @param int $amount 红包金额,单位:分
 * @param int $people 抢红包人数
 * @return array 每个人抢到的红包金额
 */
function red_packet(int $amount, int $people): array
{
    $result = []; // 抢红包结果
    $peopleSurplus = $people; // 未抢红包人数

    for ($i = 0; $i < $people; $i++) {
        if ($peopleSurplus > 1) {
            // 计算本次抢红包金额,除不尽时直接去掉小数位,不采用四舍五入方式
            $money = mt_rand(1, (int)($amount / $peopleSurplus) * 2 - 1);
            $result[] = $money;

            // 红包剩余总金额和未抢红包人数处理
            $amount -= $money;
            $peopleSurplus--;
        } else {
            // 最后一个人直接拿红包剩余金额
            $result[] = $amount;
        }
    }

    return $result;
}

$result = red_packet(100 * 100, 10); // 10人抢100元红包
echo print_r($result, true);
//========== 每个人抢到的红包金额·开始 ==========//
// Array
// (
//     [0] => 773
//     [1] => 1010
//     [2] => 1399
//     [3] => 1615
//     [4] => 789
//     [5] => 326
//     [6] => 223
//     [7] => 1699
//     [8] => 771
//     [9] => 1395
// )
//========== 每个人抢到的红包金额·结束 ==========//

echo '红包总金额(单位:分):' . array_sum($result); // 红包总金额(单位:分):10000

Copyright © 2024 码农人生. All Rights Reserved