


















这是一个创建于 432 天前的主题,其中的信息可能已经有所发展或是发生改变。
分红包,上限是总奖金 30%,下线 1 元,输入奖金总数 m 和人数 n ,输出一个列表表示每个人红包
思路一 传统分红包办法,1 到 n-1 人领随机生成 range ( 1 ,0.3*m )的红包,最后一个人拿到剩余,但是这样最后一个人可能会超出上下限
思路二 下限当作保底,先每个人分 1 元保底,剩下奖金池是 m-n ,1 到 n-1 人领取随机生成 range ( 0 ,0.3*m-1 )的红包,最后一个人拿到剩余,这样保证了下限,但是上限还是会超,如果前面 n-1 个人没分完总奖金的( 1-30%)=70%,剩下一个人就会超过上限 30%
到这里基本时间就到了,感觉凉凉,复盘时候感觉无论怎么随机分,都没法保证刚好分完
思路三是搜索到的一种解法,先计算平均值 avg ,每个人两两一对,领取 avg+-random 的红包,如果人数是单数,则返回平均值。这样能保证分完,不过额真的随机么。
1 phpfpm 2025 年 4 月 8 日1 先分保底 |
2 6HWcp545hm0RHi6G 2025 年 4 月 8 日问了下 AI # 分红包算法思路 ## 问题理解 ## 算法思路 ### 1. 输入验证 ### 2. 初始分配 ### 3. 分配剩余金额 ### 4. 具体步骤 ## Python 实现示例 ```python def distribute_red_packet(m, n): # 每人至少 1 元 for i in range(n): # 当前可分配的最大值 # 处理可能的剩余几分钱(由于四舍五入) # 再次确保没有超过上限 return result ## 注意事项 |
3 Projection 2025 年 4 月 8 日先留个保底,然后从 [0, m - n] 区间内随机 n - 1 次划分出 n 个区间,每个人取一个区间 + 保底 |
4 chachi 2025 年 4 月 8 日应该有超限重 roll 机制 |
8 moudy 2025 年 4 月 8 日直接生成 n-1 个 0-1 之间的随机数并排序,每个人拿两个相邻随机数差值 x 30%( m-0.01*n)+0.01 |
9 a0000 2025 年 4 月 8 日 via Android先分 1 块钱 |
10 geelaw 2025 年 4 月 8 日问题意思不清楚,需要明确所要的分布,假设: - 红包金额必须是整数,m 是自然数. X = { (a_1, ..., a_n) | a_i in Z, 1 <= a_i <= 0.3m, sum of a_i = m } 上的均匀分布. 又假设 m, n 不大(具体来说建模为关于 m, n 多项式时间可接受),那么最朴素的思路就是…… 固定 m, n 后,令 f(I, J) = |{ (a_1, ..., a_I) | a_i in Z, 1 <= a_i <= 0.3m, sum of a_i = J }|, 则 f(0, 0) = 1 且 f(0, J) = 0 对所有 J != 0 且 f(I, J) = sum of f(I - 1, J - a_I) over 1 <= a_I <= floor(0.3m). 考虑抽样算法 D(I, J) 表示“I 个人分配 J 元奖金”,则 D(I, J) 是: - 以 f(I - 1, J - x) / f(I, J) 的概率抽取 x ,其中 1 <= x <= 0.3m 且 x in Z . 所要求的就是运行一次 D(n, m). ———— 补充细节留给楼主:证明上述 D(n, m) 可以在 (m+n) 的多项式时间内完成. |
12 geelaw 2025 年 4 月 8 日@geelaw #10 一个简单的优化:D(I, J) 均匀随机出来一个 1 到 f(I, J) 的整数,然后按照 f 做“进位制展开”即可得到一个样本,无需递归/重新采样子问题。 |
14 oaix 2025 年 4 月 8 日不考虑分布的话,感觉可以这样分: ```python def sample(m, n): remain = m for i in range(10): |
15 renmu 2025 年 4 月 8 日 via Android如果最后一个人不符合条件,那就重新 roll |
16 hxy100 2025 年 4 月 8 日你们 v 站贴 Python 代码,缩进全无,简直要人命。 |
18 yidinghe 2025 年 4 月 9 日 via Android难道不是事先将红包先分好吗?先拆出 n 个红包,这个过程中可以二次调整,随后在领取时随机发。比如你的思路 2 中,发现有超过上限的就将超出部分补给最低的那个就行了。 |
20 sillydaddy 2025 年 4 月 9 日 via Androidv 站之前讨论过这个问题,这个问题可以看作是在一个多边形内随机取点。 |
21 lzxz1234 2025 年 4 月 9 日红包金额从 1 到 x=0.3m ,基于红包 ID 做种子生成 1 到 x 的固定随机数序列共 n 个,每个人按自己随机数占总和的比领钱 |
22 abc634 2025 年 4 月 9 日如果没有要求 随机的话,很简单? 1 , 先每人派发下限, n *1 2 , 令 (m - n ) = x (0.3m -1) +k, 其中 的商数 x 和余数 k 3 ,结果输出:x 份上限,剩下的 n-x 人从 k 里面随机抽取 再加 下限 1 。 |
23 abc634 2025 年 4 月 9 日补充:追加一个更像随机的 处理: |
24 kapaseker 2025 年 4 月 9 日不能每人一块钱,剩下的给老板吗 ? |
25 yigedala 2025 年 4 月 9 日为什么要领红包得时候,才生成一个随机的金额? |
27 InDom 2025 年 4 月 9 日先每个人保底分配 1 元, 然后求出剩余奖金的平均值, 然后循环给每个用户随机分配奖金 循环随机分配时随机数动态分配, 每个用户随机范围为 0 到 剩余平均值 + 上次循环剩余奖金, 如果剩余平均值 + 上次循环剩余奖金 > %30-1, 则最小值 + (剩余平均值 + 上次循环剩余奖金 - %30-1). 大概思路如此, 理论上可以保证每次随机都会在上限内分配, 如果上一个人分配的少了, 下一个人就有更高概率分配更多一点. |
28 runlongyao2 2025 年 4 月 9 日//m 是金额,n 是人数 m = m - n while(m){ _n[index].value++ if(_n[index].value > maxValue){ result = [...result, ..._n].sort((a,b)=>a.index > b.index) return result function getRandomInt(max) { |
29 InkStone 2025 年 4 月 9 日随机+拒绝采样就是最简单也最实用的做法,不用想那么多复杂的…… |
31 chairuosen 2025 年 4 月 9 日方法二:第 i 个人并不是 range ( 0 ,0.3*m-1 ),而是 range ( max(0, m-0.3*(n-i)) ,0.3*m-1 )也就是要保证 i 至少分一个钱数,让后面人卡着最大值能满足不超。当然这样会导致后几个人得到大红包的概率高,只需排好再打乱排序即可 |
32 edward1987 2025 年 4 月 9 日你的思路二扩展下就行 [当最后一人超出 30%,则取 30%,多出的金额给剩下的没有达到上限的人随机] 重复操作这个步骤就行 |
33 gxt92 2025 年 4 月 9 日想到一种思路🤪 |
34 zoyao 2025 年 4 月 9 日1 + ramdom(0, min(0.3m, 剩余奖金)) |
36 Yanlongli 2025 年 4 月 9 日大脑:这不是简简单单有手就行 额滴神啊 // php 代码,带 <? 提示 cf 拦截 $list = []; for ($i = 0; $i < $count; $i++) { // 最后 10w 测试发现,第一个抽的人很亏,所以把所有人的抽奖打乱一下 shuffle($list); // 当当当当 10w 结果看上去 OK 了 |
37 littleW2B 2025 年 4 月 9 日这不就是 softmax 吗。都不用 e ,直接在 0 到 max 之间 random N 个数,然后每个数除以总和乘以红包总额,向下取整,把最后的差额一人一块分了。 |
38 knight618 2025 年 4 月 9 日思路就是默认每人一块,剩下的钱一块块的随机给一个人 def main(m, n): re_ = [1 for i in range(n)] # 默认每人一块 if __name__ == "__main__": |
40 senghoo 2025 年 4 月 9 日我感觉本质上是一个约束比较宽泛的约束满足问题。与地图填色、八皇后之类的是一类问题。 然后各类搜索算法跑起来~ |
41 Huelse 2025 年 4 月 9 日在创建红包的时候就按数量分好金额池,然后随机抽就完了 |
44 gwbw 2025 年 4 月 9 日思路三没什么问题,你可能纠结的"随机"是数学上的随机,工程上只要在最后分的时候把顺序打乱,整体就是公平的。类似于切蛋糕的和分蛋糕的不是同一个人,无论切蛋糕的人怎么切,只要分蛋糕的人闭着眼睛随机分,大家的期望就都一样 |
45 yankebupt 2025 年 4 月 9 日哎……多少次了,AI 回答贴个分享链接就行了不要贴结果不要贴结果,又拜拜了一个账号 |
46 yc8332 2025 年 4 月 9 日上下限差太多,又限制单包。。基本下限就没用了。 |
48 bloodspasm 2025 年 4 月 9 日如果是 2 个人分 100 块钱, 会怎么样? 😅 |
49 vincentWdp 2025 年 4 月 9 日1 楼的答案很好啊. 补充一下: |
50 BreadKiller 2025 年 4 月 9 日想了一下,感觉只能事先按人数分配好红包金额,不能每次去获取的时候再去计算红包金额。在此前提下,想了一个方案: 用 js 写了一下 金额是乘了 100 用整数算 while (sum < m) { |
51 lff0305 2025 年 4 月 10 日每个人依次生成随机数,如果满足条件且小于剩余钱数,给这个人分钱,对下一个人; import java.util.Arrays; public class RedBag { private Random random = new Random(); public static void main(String[] args) { /// result: Result for each persion // Last person, and the left money is OK // left money cannot give at least $1 per person int value = 0; |
52 rainbowhu 2025 年 4 月 10 日这样的吗? 对于总量 m 和个数 n ,以及最大比例 r, 每次确定随机范围[x, y] x >= 1 -> x = max(1, m - (n - 1) * r * m) y <= r * m -> y = min(r * m, m - (n - 1) * 1) |
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。