洛谷p2404 自然數的拆分 2019.7.25
題目描述
任何乙個大於1的自然數n,總可以拆分成若干個小於n的自然數之和。現在給你乙個自然數n,要求你求出n的拆分成一些數字的和。每個拆分後的序列中的數字從小到大排序。然後你需要輸出這些序列,其中字典序小的序列需要優先輸出。
輸入格式
輸入:待拆分的自然數n。
輸出格式
輸出:若干數的加法式子,方案總數。
輸入輸出樣例
輸入 #1 複製
7輸出 #1 複製
7=1+1+1+1+1+1+1
7=1+1+1+1+1+2
7=1+1+1+1+3
7=1+1+1+2+2
7=1+1+1+4
7=1+1+2+3
7=1+1+5
7=1+2+2+2
7=1+2+4
7=1+3+3
7=1+6
7=2+2+3
7=2+5
7=3+4
total=14
審題:1.按字典序排列,後面新增的數始終大於等於前乙個數字。
2.sum=n
演算法及思路:
1.既然可以從小找到大,考慮用深,遍歷所有小於n的數+記憶化搜尋來做
2.dfs函式的設定,考慮當前狀態:
比如待拆分的數字為num,可以考慮減去從i到num-1的所有數,這個地方可以考慮用迴圈來找減數,同時注意到減數受到來自前一步的減數的限制,這一步的數必須大於等於前一步的數,設該減數為t。那麼此時num=num-t,問題轉化為拆分num-t,可以用遞迴實現。
3.從上方的描述中可以看出,dfs函式需要維護至少兩個引數:當前正在拆分的數以及當前拆分的次數。前者容易明白,後者呢??因為受到來自前乙個減數的限制,可以考慮用乙個陣列a來記錄每一步的減數,那麼要求i>=a[step-1]即可!!!同時,由於記錄了每一步的減數,那麼最後當num==0時列印拆分數序列的問題也就迎刃而解了(只需要遍歷從a陣列1到step的所有元素即可)。同時,保留了前一種拆分方法的主體,當dfs函式返回上層棧時,只需要更改最後的幾個數就行了,不必重新遍歷前方的選擇值。
元素解釋:
dfs(int num,int step) 申明dfs維護的兩個狀態:當前正在拆分的數,和已拆分次數
a[maxn] 每一步拆分改變的數
print() 用來列印各種拆分序列
total 計數器,用來記錄拆分的方法數
#include//cin、cout標頭檔案
#define maxn 100100 //巨集定義maxn
using namespace std;
int n,total; //給出待拆分數n,拆分方法total
int a[maxn]=; //因為每一步所拆分的資料至少為1,故初始化為1.
void print(int x)//列印函式,x儲存當前的拆分方法所需要的拆分次數
自然數拆分
描述 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個數的和以及取值範圍。可以先用貪心演算法構造乙個最小的...