發出一個固定金額的紅包,由若干個人來搶,需要滿足哪些規則?
1.所有人搶到金額之和等於紅包金額,不能超過,也不能少於。
2.每個人至少搶到一分錢。
3.要保證所有人搶到金額的幾率相等。
參考:程序員小灰——漫畫:如何實現搶紅包算法?
剩余紅包金額為M,剩余人數為N,那么有如下公式:
每次搶到的金額 = 隨機區間 (0, M / N X 2)
這個公式,保證了每次隨機金額的平均值是相等的,不會因為搶紅包的先后順序而造成不公平。
舉個栗子:
假設有10個人,紅包總額100元。100/10X2 = 20, 所以第一個人的隨機范圍是(0,20 ),平均可以搶到10元。
假設第一個人隨機到10元,那么剩余金額是100-10 = 90 元。90/9X2 = 20, 所以第二個人的隨機范圍同樣是(0,20 ),平均可以搶到10元。
假設第二個人隨機到10元,那么剩余金額是90-10 = 80 元。80/8X2 = 20, 所以第三個人的隨機范圍同樣是(0,20 ),平均可以搶到10元。
以此類推,每一次隨機范圍的均值是相等的。static void Main(string[] args) { //例子:50元分配10個人 List<int> amountList = divideRedPackage(5000, 10); foreach (double amount in amountList) { double item = (amount / 100); Console.WriteLine($"搶到金額:{item}"); } } //發紅包算法,金額參數以分為單位 public static List<int> divideRedPackage(int totalAmount, int totalPeopleNum) { List<int> amountList = new List<int>(); int restAmount = totalAmount; int restPeopleNum = totalPeopleNum; Random random = new Random(); for (int i = 0; i < totalPeopleNum - 1; i++) { //隨機范圍:[1,剩余人均金額的兩倍),左閉右開 int amount = random.Next(restAmount / restPeopleNum * 2 - 1) + 1; restAmount -= amount; restPeopleNum--; amountList.Add(amount); } amountList.Add(restAmount); return amountList; }
