整數劃分為多數之和

2021-10-10 13:45:03 字數 1873 閱讀 9312

將整數n,劃分為m個整數的和(1≤

m≤n)

(1 \le m \le n)

(1≤m≤n

),求有多少種加法結果。

聯想到抽屜原理

容易得出,兩種極端情況。

m =n

m = n

m=n,抽屜數等於item個數,這意味著只有一種分法

m =1

m = 1

m=1,只有乙個抽屜,怎麼分都也是只有一種分法

那麼,就剩下一種最一般的情況了。

n

>

mn > m

n>

m, 抽屜的個數小於item個數

思路:先給每個抽屜都派乙個item,盈餘的item數surplus為n−m

n - m

n−m,

然後,將surplus按照其公因數分配到抽屜中(那麼k個公因數也就有k種抽屜分配情況),構造出所有的抽屜,再計算所有抽屜的組合數之和,即計算結果。

from itertools import permutations

# 計算排列組合個數

defcombines

(_set)

:return

len(

set(permutations(_set,

len(_set)))

)def

get_cnt

(_desk, _num)

:if _num <

0or _desk <0:

return

0if _desk ==

1or _desk == _num:

# 兩種特殊的情況

return

1 cnt =

0# 累計當前所有排列可能

surplus = _num - _desk # 給每個抽屜分配乙個item後的盈餘的個數

shares =

(x for x in

range(1

, surplus +1)

if surplus <= x * _desk)

# 盈餘個數的可劃分份數集

# 根據每次放入不同的份數,構造不同的抽屜

for x in shares:

tmp = surplus

drawers =[1

]* _desk # 生成抽屜並向每個抽屜放入乙個item

index =

0while tmp >0:

if tmp < x:

# 剩餘的盈餘數少於單份放入抽屜的數量

drawers[index]

+= tmp

tmp =

0else

: drawers[index]

+= x

tmp -= x

index +=

1 cnt += combines(drawers)

# 計算序列組合數

return cnt

defsolution()

: cnt =

0 n =

int(

input

("請輸入整數n:"))

for i in

range(1

, n +1)

: cnt += get_cnt(i, n)

return cnt

print

(solution(

))

將乙個整數劃分為多個正整數之和

整數劃分問題是將乙個正整數n拆分成一組數連加並等於n的形式,顯然這組數中最大加數不大於n。令n為需要劃分的整數,m為劃分後的最大整數。例如將6劃分為最大加數為6的劃分形式如下 5 1 4 2,4 1 1 3 3,3 2 1,3 1 1 1 2 2 2,2 2 1 1,2 1 1 1 1 1 1 1 ...

將乙個整數劃分為多個正整數之和

整數劃分問題是將乙個正整數n拆分成一組數連加並等於n的形式,顯然這組數中最大加數不大於n。令n為需要劃分的整數,m為劃分後的最大整數。例如將6劃分為最大加數為6的劃分形式如下 65 1 4 2,4 1 1 3 3,3 2 1,3 1 1 1 2 2 2,2 2 1 1,2 1 1 1 1 1 1 1...

基本演算法 拆分為連續正整數之和

整數拆分 即把乙個給定的正整數拆分為若干個連續正整數之和 例如 將輸入乙個整數15,可以拆分為 15 1 2 3 4 5 15 4 5 6 15 7 8 分析 由題可知,拆分的起始項i不會超過該數n的一半減一 1 n 1 2 累加項不會超過該數的一半加一 i n 1 2 這裡可以作為迴圈的條件,在j...