2048: 令D(n,n)爲n人都拿到別人字條的狀況數,則可知D(n,n)/A(n,n)爲此狀況出現的機率。首先有D(2,2)=1(即[2,1]), D(3,3)=2([2,3,1]和[3,1,2])。觀察D(4,4)的全部9種狀況([2,1,4,3],[3,1,4,2],[4,1,2,3],[2,4,1,3],[3,4,1,2],[4,3,1,2],[2,3,4,1],[4,3,2,1],[3,4,2,1]),能夠將這9種狀況分爲兩組:
1) 在D(3,3)的全部狀況後加入4,而後將4與前面的元素逐一調換,得出的每一種狀況都不重複且屬於D(4,4):[2,3,1,4]=>[4,3,1,2],[2,4,1,3],[2,3,4,1]; [3,1,2,4]=>[4,1,2,3],[3,4,2,1],[3,1,4,2]。該狀況的數量爲D(3,3)*3;推廣開來,對於D(n+1,n+1),狀況數爲D(n,n)*n;
2) 對於全部的D(3,2)狀況(3人中2人拿到別人字條,1人拿到本身字條),即[1,3,2],[3,2,1],[2,1,3]添加4後,將4與拿到本身字條的人交換位置,也能夠生成合法狀況:[1,3,2,4]=>[4,3,2,1]; [3,2,1,4]=>[3,4,1,2]; [2,1,3,4]=>[2,1,4,3]。接下來再考慮D(3,2)的計算,它實際上能夠看做是在D(2,2)上直接添加一我的獲得,此時3人分爲AB兩組:A組2人都沒有拿到本身的字條,B組1人拿到本身字條。A組的構成方法有C(3,2)種(也能夠構成B組C(3,1),這是等價的,由於C(m,n)=C(m,m-n))。A組的組內狀況有D(2,2)種,所以一共有C(3,1)*D(2,2)=D(2,2)*3種,推廣開來,對於D(n+1,n+1),狀況數爲D(n-1,n-1)*n
將狀況1)和2)相加可得遞推公式D(n+1,n+1)=(D(n,n)+D(n-1,n-1))*n,其中初始狀態D(2,2)=1,D(3,3)=2. 數值較大,建議使用unsigned long long
2049: 令D(m,n)爲m對中n對配對錯誤的狀況數,首先根據2048中的解法可求得全部D(m,m) (m in (1,20])的值,如今的問題變爲如何求D(m,n) (m>n)。首先將m人分爲AB兩組:A組爲n對配對錯誤的,B組爲m-n對配對正確的。AB兩組的分組方案有C(m,n)種,而對於A組,組內狀況有D(n,n)種,對於B組,組內狀況數爲1,所以D(m,n)=D(n,n)*C(m,n)
OJ刷題真心挺好玩的,可謂寓教於樂的算法學習方法…