红包算法
5.红包算法
题目
一个关于钱的需求。
发红包功能,例如一个人的群里发了100红包,群里有10个人一起来抢红包,每个人的金额随机分配。
抢红包规则
- 所有人抢到的金额之和要等于红包金额。
- 抢到红包的人至少抢到1分钱。
- 尽可能保证红包拆分的金额分布均衡,不要出现两极分化太严重的情况。
思路
二倍均值法
假设红包剩余金额为x元,剩余人数y人,有如下公式:抢到的m(金额)=[0.001,x/y * 2 - 0.01]元
这个公式,保证了每次随机金额的平均值是相等的,不会因为抢红包的先后顺序而造成不公平。
举例
假设有5个人,红包总额100元。
100/5 * 2 - 0.0.1 = 39.9,第一个人抢到的金额随机范围是[0.01,39.9],在数据量多
的情况下,接近正态分布,平均可抢到20元。
80/4 * 2 - 0.01 = 39.9元,假设第2个人随机抢到了20元,那么剩余金额是60元。
60÷3×2 = 40,所以第3个人抢到的金额的随机范围同样是[0.01,39.99]元,平均可以抢到20元。 以此类推,每一次抢到金额随机范围的均值是相等的。
代码
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class RedPackage {
/**
* @param totalAmount 总金额(单位 分)
* @param totalPeopleNum 总人数
* @return
*/
public static List<Integer> divideRedPackage(int totalAmount, int totalPeopleNum) {
List<Integer> amountList = new ArrayList<>();
int restAmount = totalAmount;
int restPeopleNum = totalPeopleNum;
Random random = new Random();
for (int i = 0; i < totalPeopleNum - 1; i++) {
int amount = random.nextInt(restAmount/restPeopleNum * 2 - 1) + 1;
restAmount -= amount;
restPeopleNum--;
amountList.add(amount);
}
amountList.add(restAmount);
return amountList;
}
public static void main(String[] args) {
for(Integer amount : divideRedPackage(10000,10)){
System.out.println("抢到金额: " + new BigDecimal(amount).divide(new BigDecimal(100)) + "元");
}
}
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· spring官宣接入deepseek,真的太香了~