整數劃分為多數之和
題目簡述
將整數n,劃分為m個整數的和 ( 1 ≤ m ≤ n ) (1 \le m \le n) (1≤m≤n),求有多少種加法結果。
- 額外條件: 整數的順序也影響結果。
解決方案
解法一、列舉
思考
聯想到抽屜原理
-
將整數n理解為有n個item,將列舉過程理解為,將n個item放到m個抽屜中
-
現在的問題就在於如何分配item?
容易得出,兩種極端情況。
- m = n m = n m=n,抽屜數等於item個數,這意味著只有一種分法
- m = 1 m = 1 m=1,只有一個抽屜,怎麼分都也是隻有一種分法
那麼,就剩下一種最一般的情況了。
-
n
>
m
n > m
n>m, 抽屜的個數小於item個數
思路:先給每個抽屜都派一個item,盈餘的item數surplus為 n − m n - m n−m,
然後,將surplus按照其公因數分配到抽屜中(那麼k個公因數也就有k種抽屜分配情況),構造出所有的抽屜,再計算所有抽屜的組合數之和,即計算結果。
- 注意:對於由於 n > m n > m n>m 即使是加上盈餘也存在越界的可能,那麼當其越界的時,從列表的首元素開始加即可。
python程式碼實現:
from itertools import permutations
def combines_of_set(_set):
return len(set(permutations(_set, len(_set))))
def get_cnt(_desk, _num):
if _desk == 1: # 特殊情況只有一個抽屜
return 1
cnt = 0 # 計數當前所有排列可能
surplus = _num - _desk # 給每個抽屜分配一個item後的盈餘的個數
if surplus == 0: # 特別情況無盈餘
return 1
shares = (x for x in range(1, surplus + 1) if surplus % x == 0) # 盈餘個數的可劃分份數集
for x in shares:
tmp = surplus
items = [1] * _desk # 生成抽屜並向每個抽屜放入一個item
index = 0
while tmp > 0:
if index == _desk: # 越界則從頭加
index = 0
items[index] += x
index += 1
tmp -= x
cnt += combines_of_set(items) # 計算序列組合數
return cnt
def solution():
cnt = 0
n = int(input("請輸入整數n:"))
for i in range(1, n + 1):
cnt += get_cnt(i, n)
return cnt
print(solution())
相關文章
- 尤拉計劃621:把整數表示為三角數之和
- 整數劃分(硬幣問題)(dp)
- 尤拉計劃725:數位之和數
- 兩數之和,三數之和,最接近的三數之和,四數之和
- 整數二分
- 01 分數規劃
- 01分數規劃
- 輸入一個非負整數,返回組成它的數字之和
- 怎樣解題|題2.4.9:連續正整數之和
- 兩數之和
- 三數之和
- CCF 201512-1 數位之和 python 滿分Python
- 求兩個整數之和——一個寫註釋的新手
- 【leetcode 簡單】 第八十七題 兩整數之和LeetCode
- 轉換成為整數
- Cplex混合整數規劃求解(Python API)PythonAPI
- Python小白的數學建模課-04.整數規劃Python
- 動態規劃之數的劃分動態規劃
- LeetCode - 兩數之和LeetCode
- 兩數之和(TwoSum)
- LeetCode:兩數之和LeetCode
- 判斷一個數為哪些數的階乘之和(貪心)
- 引數為二叉樹和一個整數,求所有和為該整數的路徑二叉樹
- 分數規劃P3199
- L1-025 正整數A+B 分數 15
- LeetCode 343. 整數拆分--動態規劃LeetCode動態規劃
- 運籌優化(九)--整數規劃模型優化模型
- 運籌優化(十)--整數規劃求解優化
- 羅馬數字轉化為整數的方法
- 633. 平方數之和 ( 列舉 + 二分查詢 )
- 18_四數之和
- LeetCode-兩數之和LeetCode
- 1. 兩數之和
- 633. 平方數之和
- leetcode #1 兩數之和LeetCode
- LeetCode 1 兩數之和LeetCode
- LeetCode之兩數之和LeetCode
- 15.三數之和