一百顆糖,發給十個小朋友,要求每個小朋友都有糖,且不存在兩個小朋友手上的糖一樣多,問一共有多少種分法?
正兒八經的數學問題,本人大三,解不出來,感覺理科生的尊嚴遭到了挑戰
SeriesCoefficient[
Product[1/(1 - x^n), {n, 10}], {x, 0, 45}]
最終答案是 33401 種。
小孩都看成一樣的話,題目就是要求 在 時的整數解。令 . 則所有的 都是非負整數。原方程現在變成了 . 這個方程的非負整數解就是級數 在 處的係數。然後用 Mathematica 算出了答案。如果小孩不一樣,將前面的結果乘以 就可以了。如果不考慮小朋友之間的區別,即A分到2顆B分到1顆的情況和A分到1顆B分到2顆的情況視為同一種,那麼共有33401種分法如果考慮小朋友之間的區別,那麼共有33401*10! = 121205548800種分法
用Mathematica純暴力枚舉的,算了8秒多出的結果,代碼如下,ans里保存了所有可能的分配方法。
ans = Select[IntegerPartitions[100, {10}], UnsameQ @@ # ];
num = Length[ans]
num*10!
更新了簡單解釋
=============================題目就是求n分成m個不同正整數(不考慮順序)的和的方法數,直觀上就和劃分數同一難度的。方法也基本一樣:生成函數( @鄭育強 ),暴力( @無影東瓜 等),和遞推:
令f[n, m, min]表示把n分成m個不同正整數(不考慮順序)的和並且每個數都不小於min的方法數,則f[n_, 1, min_] := Boole[n &>= min]
f[n_, m_, min_] := Sum[f[n - i, m - 1, i + 1], {i, min, n/m}]
第一行是指把n分成1份,並且這一份&>=min的方法數。顯然當n&>=min時為1,否則為0;
第二行是考慮這m份中最小的一份,設為i。除去這一份,剩下的n-i分成了m-1份,並且每份都&>=i+1。考慮所有可能的i並求和就是最後結果。結果就是f[100, 10, 1]
33401
菜魚ftfish 的方法可以進一步優化,例如 f[n_, m_, min_] 實際上可以寫成 f[n_-m_*(min_-1), m_, 1]這樣就能把 min 這個維度消掉,方程改寫如下
f[n_, 1] := Boole[n &> 0]
f[n_, m_] := Sum[f[n - i * m, m - 1], {i, 1, n/m}]
我試著計算了一下,然後突然有了一種想舉報這個問題的衝動。。。。。。。。。
#coding=utf-8
#此為python代碼
child = [0]*10
n = 0
COUNT = 0
f = open(/Users/pengzhenghao/desktop/result.txt, w)
#遞歸函數。第一項為待分割的數(即上次分割之後右邊的數)。第二項為上次
#分割之後,左邊的數。第三項為數組。第四項為遞歸層數,或者是待填充的數組的下標。
def setnumber(divide, lastleft, list, tier):
#引入全局變數計數
global COUNT
for i in range(lastleft+1, 101):
list[iter] = i #把數字divide分成左右兩部分
list[iter+1] = divide-i
if list[iter+1] &<= list[iter]:#循環出錯,退出
break
if iter == 8: #遞歸終止條件
f.write(str(list)) #寫入文件
COUNT += 1 #計數
continue
setnumber(list[iter+1], list[iter], list, iter+1)
#開始運算
setnumber(100,0,child,0)
print(COUNT)
f.close()
拙作一篇,結果是33401。
另外這是不考慮小朋友全排列的結果。小朋友的全排列是Length[Solve[
q + w + e + r + t + y + u + i + o + p == 100
q &> w &> e &> r &> t &> y &> u &> i &> o &> p &> 0, {q, w, e, r, t, y, u, i,
o, p}, Integers]]
雖然有點蠢。。。殺死九個小朋友。
這是你侄子問你的暑假作業嗎?
百度:小學奧數-插板法。純理論演算法的話
我不知道你理論基礎到多少
但現在我只知道非同步差分,直接套公式就可以。三十年前的十萬個為什麼里有類似的題
頂上一隊大神都給出了理論演算法,這裡給個學渣演算法。寫個程序枚舉唄_(:з」∠)_
這個題可能性太多了,前面大神的解答還看不懂,感覺數學白學了
def sugar(k,x,aj):
if sum(range(aj+1,aj+12-k))&>x:return 0
elif k==10:return 1
else:return sum([sugar(k+1,x-ak,ak) for ak in range(aj+1,x+1)])
print(sugar(1,100,0))
硬生生湊起來的代碼,其中的數學部分都是中學水平,應該很容易看懂 (??ˇ_ˇ??) 。
算下來1秒不到,核心思想就是x0&
先要個位置,回家後答題。
推薦閱讀:
※概率是主觀的嗎?
※一個箱子有50隻球,一半黑,一半白,取球要放回。你有200次機會取球。問把所有黑球都取過至少一次幾率?
※預備篇 II :隨機場的存在性
※隨機分析(下)