題目描述任何乙個大於 1
11 的自然數 n(n
≤45
)n(n≤45)
n(n≤45
) ,總可以拆分成若干個小於 n
nn 的自然數之和。
輸入格式輸入只有 1
11 行,包含 1
11 個整數 n
nn ,表示需要拆分的數字。
輸出格式對於輸入的 n
nn ,輸出所有的拆分方法 (字典
序小的先
輸出
)(字典序小的先輸出)
(字典序小的
先輸出)
,每種拆分方法佔 1
11 行,最後輸出一共有多少種拆分方案。
樣例這是一道典型的 搜尋搜尋樣例輸入
樣例輸出
4=1+1+1+1
4=1+1+2
4=1+3
4=2+2
4
搜尋題。由於要輸出拆分的序列,我們可以用 ans
[]
ansan
s[] 來儲存答案序列,也可以推出 ans
[i
]>
0ans[i] > 0
ans[i]
>
0 , ans
[i−1
]≤an
s[i]
ans[i-1] ≤ ans[i]
ans[i−
1]≤a
ns[i
] 。可以定義乙個搜尋函式 dfs
dfsdf
s ,即 dfs (intk,intnum,intsum ) ,表示為 " 在求 ans
[k
]ans[k]
ans[k]
時,上一次求得的 ans
[k−1
]ans[k - 1]
ans[k−
1]為 num
numnu
m ,剩下還需要拆分的數為 sum
sumsu
m 。 "
在求第 k
kk 個的時候,我們可以迴圈列舉 num
numnu
m 到 sum
sumsu
m 之間的所有數,來求得 ans
[k
]ans[k]
ans[k]
的所有情況,即:
for
(int i = num; i <= sum; i++
)
如果 sum
=0
sum=0
sum=
0 ,說明 ans
[]
ansan
s[] 裡儲存的數加起來就已經等於 n
nn 了,就不需要繼續往下搜尋了。
但這時候的 ans
[k
]ans[k]
ans[k]
是沒有數的,又因為 ans
[]
ansan
s[] 中不能只有 1
11 個數,所以在 k−1
>=2
k - 1 >= 2
k−1>=2
即 k>
2k > 2
k>
2
if
(sum ==0)
正解**就下面(但是不要抄襲喲~):
#include
const
int maxn =50;
int n;
int ans[maxn]
;// 用來儲存答案序列
int tot;
// 用來儲存答案個數
void
print
(int k)
// 輸出答案
void
dfs(
int k,
int num,
int sum)
// 第n個(ans[n]), 前乙個數為num(ans[n-1]=num), 剩下的數為sum
for(
int i = num; i <= sum; i++)}
void
input_output()
intmain()
自然數拆分
描述 description 輸入自然數n,然後將其拆分成由若干數相加的形式,參與加法運算的數可以重複。輸入格式 inputformat 輸入只有乙個整數n,表示待拆分的自然數n。n 80 輸出格式 outputformat 輸出乙個數,即所有方案數 樣例輸入 sampleinput 複製資料 7 ...
自然數拆分
問題描述 自然數的拆分 任何乙個大於1的自然數n,總可以拆分成若干個自然數之和,並且有多種拆分方法。試求 n的所有拆分。例如自然數5,可以有如下一些拆分方法 5 1 1 1 1 1 5 1 1 1 2 5 1 2 2 5 1 4 5 2 3 注意,本題中n拆分出來的數x的範圍是1 x整數劃分可以參考...
自然數拆分
題目 給出sum min max和n四個正整數,請輸出所有將sum拆分為n個遞增的正整數 允許相等 之和,其中每個正整數k都滿足 min k max。在少俠的部落格 看到這道題 就隨手做了下。該題與輸出n個數取m個數的所有組合類似,只不過限定了m個數的和以及取值範圍。可以先用貪心演算法構造乙個最小的...