设sum=100
,n=10
,则题目可以得到以下结论6n <= sum <= 12n
。
设randNum
为随机红包的大小,则可以推出6(n-1) <= (sum-randNum) <= 12(n-1)
从上面的结论里我们可以得到以下答案
function makeSeq(){
$n = 10;
$sum = 100;
$result = [];
while ($n > 1) {
// 6n <= sum <=12n
$randNum = mt_rand(600,1200) / 100;
if(($sum-$randNum) >= 6* ($n - 1) && ($sum-$randNum) <= 12* ($n - 1)){
$sum -= $randNum;
$n -= 1;
$result[] = $randNum;
}
}
$result[] = $sum;
return $result;
}
进阶
上面的答案效率不是很高,其实我们可以通过计算红包的上下界,然后通过一次随机得到答案。
由6(n-1) <= (sum-randNum) <= 12(n-1)
可得sum - 12(n-1) <= randNum <= sum - 6(n-1)
。
又由6 <= randNum <= 12
计算得到红包的上下界:
$min = ($sum - 12 * ($i-1))>6?($sum - 12 * ($i-1)):6;
$max = ($sum - 6 * ($i-1))<12?($sum - 6 * ($i-1)):12;
则最终答案是
function makeSeq2(){
$n = 10;
$sum = 100;
$result = [];
for($i=$n;$i>=1;$i--){
$min = ($sum - 12 * ($i-1))>6?($sum - 12 * ($i-1)):6;
$max = ($sum - 6 * ($i-1))<12?($sum - 6 * ($i-1)):12;
$randNum = mt_rand($min,$max);
$sum -= $randNum;
$result[] = $randNum;
}
return $result;
}