整數劃分(遞迴,附程式執行過程)
阿新 • • 發佈:2019-01-08
問題描述: 任何一個大於1的自然數N,總可以拆分成若干個小於n的自然數之和。
輸入: n
輸出:按字典序輸出具體方案。
我們以 n = 4 為例說明一下執行過程, 下附程式碼
我們以 n = 4 為例說明一下執行過程 閱讀本段 一定要注意各個變數值的變化 cin >> n = 4, 進入func函式 此時 s = 4, t = 1; for 迴圈 i = a[1-1] = 1 1 < 4 => a[1] = 1, s = 3; s = 3 != 0 遞迴進入下一層 ***我們在這裡做一下標記,方便回溯 第二層 s = 3, t = 2 i = a[2-1] = 1 不知道為什麼看第五行 i < s, i < n => a[2] = 1, s = 2; s = 2 != 0 繼續遞迴進入下一層 *** 第三層 s = 2, t = 3; 步驟類似前面的 最後 s = 1, a[3] = 1 s = 1 != 0 繼續遞迴進入下一層 **** 第四層 s = 1, t = 4; 這一層for迴圈只執行一次 因為 i = 1, s = 1 a[4] = 1, s = 0; print(t); 輸出了 4 = 1+1+1+1; 開始回溯 我們注意到 在第三層 s = 2, i = 1, 故for迴圈執行兩次 第二次for迴圈 i = 2, s = 2 這一層變數的值 i = 2,s = 2, t = 3, a[0]~a[4] 都是 1 迴圈體裡a[3] = i = 2, s = 2 - 2 = 0 執行print(t) 要注意一下print函式輸出是a[1] 到 a[t] 所以輸出的是 4 = 1 + 1 + 2; 下面的輸出原因也是一樣 至此第三層的for迴圈也執行完畢 變數值 a[0] = a[1] = a[2] = a[4] = 1, a[3] = 2; 回溯到第二層, 第二層的for迴圈只執行了一次 但是本層初始值 i = 1, s = 3, t = 2, 所以還有兩次for迴圈沒有執行 第二次for迴圈 i = 2 迴圈體內 i < n, a[2] = 2, s = 3 - 2 = 1 s != 0 注意了, 我們又要遞迴了 *** 標記一下, 一會回溯到此處 第五次遞迴 a[0] = 1, a[1] = 1, a[2] = 2, a[3] = 2, a[4] = 1; s = 1, t = 3 初始i = a[2] = 2 注意前文陣列a中值的變化 a[2] 已經是2了 i = 2, 但是 s = 1 for迴圈不執行 直接回溯到剛才標記到地方, 進行第三次for迴圈 第二層第三次for迴圈 i = 3, s = 3, t = 2 3 < 4 => a[2] = 3 s = 3 - 3 = 0; s = 0, 執行print(t) 輸出 4 = 1 + 3 到此處 第二層的for迴圈執行完畢 a[0] = 1, a[1] = 1, a[2] = 3, a[3] = 2, a[4] = 1 回溯到第一層, 第一層初始 i = 1, s = 4, 應執行四次for迴圈 現執行第二次for迴圈 i = 2, s = 4, t = 1 2 < 4 => a[1] = 2, s = 4 - 2 = 2 s = 2 != 0 進行遞迴 第六次遞迴 s = 2, t = 2 a[0] = 1, a[1] = 2, a[2] =3, a[3] = 2, a[4] = 1 初始 i = a[2-1] = 2, s = 2 執行一次for迴圈 i = 2 < 4 => a[2] = 2, s = 2 - 2 = 0; s = 0 執行print(t) 輸出 4 = 2 + 2 // 在此處所有情況以輸出完畢 執行完畢, 回溯 回溯到第一層 執行第三次for迴圈 i = 3, s = 4, t = 1 i < n => a[1] = 3, s = 4 - 3 = 1; s = 1 != 0 進行遞迴 第七次遞迴 a[0] = 1, a[1] = 3, a[2] = 3, a[3] = 2, a[4] = 1; 初始 s = 1, t = 2, i = a[2-1] = 3 i > s, 不執行for迴圈,直接回溯 回溯到第一層 執行第四次for迴圈 i = 4, s = 4, t = 1 迴圈體內 i = 4, n = 4, i < n 不成立 往下不在執行, 跳出迴圈 至此所有程式執行完畢, 返回到主函式
#include <iostream> using namespace std; const int MAXN = 100000+7; int n, total = 0; int a[MAXN] = {1}; // 初始a[0] = 1, 其餘全為0 void print(int t) { total ++; cout << n << "="; for(int i=1; i<=t; i++) { if(i == t) // 最後一個數時執行這一步 cout << a[i] << endl; else cout << a[i] << "+"; } } int func(int s, int t) { for(int i=a[t-1]; i<=s; i++) { if(i < n) { a[t] = i; s = s - i; if(s == 0) print(t); else func(s, t+1); s += i; } } return 0; } int main() { cin >> n; func(n, 1); cout << total << endl; return 0; }