自然數的拆分(完全揹包)

2021-10-06 01:49:33 字數 1259 閱讀 4641

給定乙個自然數n,要求把n拆分成若干個正整數相加的形式,參與加法運算的數可以重複。與「自然數拆分問題」類似,同樣需要滿足方案的不重複。

所謂拆分方式的重複性判定如下:給定n=a

​1​​ +a

​2​​ +…a

​m1​​ 和 n=b

​1​​ +b

​2​​ +…b

​m2​​ 表示整數n的兩種拆分方式。對於∀a

​i​​ ,b

​j​​ ≥1,令集合a=,b=。若滿足集合a=b,則稱這兩種拆分方式是重複的。

例如 6 = 3 + 2 和 6 = 2 + 3, 就是重複的拆分方式。

現在需要你求滿足條件的拆分有多少種?

輸入格式:

第一行自然整數t,表示之後測試資料組數, 以後t行,每行乙個自然數n,(1注意:本題規模為4000,回溯法還合適嗎?仔細思考應該如何設計演算法

建議自行學習完全揹包相關知識

輸出格式:

t行,每行輸出乙個整數,表示拆分的方案數,結果對2147483648取模。

輸入樣例:

在這裡給出一組輸入。例如:

267

輸出樣例:

在這裡給出相應的輸出。例如:

11

15

分析:

雖然可以用回溯法去解決,但是當規模大的時候,回溯法需要的時間太長。就使用完全揹包知識。

思路:

將乙個數差分成若干個數,很顯然其中某些數可能會出現多次, 就是說這些數可以用無限多次來構成最初的數,這就是完全揹包問題:有n個物品,每個物品可以選無限多次,求選出的若干個物品的價值之和恰好為n的方案個數。

在完全揹包中 狀態轉移方程

dp[i][k] = dp[i][k - 1] + dp[i - num[k]][k];

很明顯,兩者如出一轍,只是變成了一維。

#includeusing namespace std;

const int max = 4001;

const int mod = 2147483648;

int n;

void oper();

cin >> n;

dp[0] = 1;

for(int i = 1; i <= n; i++)

}cout << dp[n]<>t;

while(t>0)

return 0;

}

完全揹包問題 自然數拆分

給定乙個自然數n,要求把n拆分成若干個正整數相加的形式,參與加法運算的數可以重複。求拆分的方案數 mod 2147483648的結果。輸入格式 乙個自然數n。輸出格式 輸入乙個整數,表示結果。資料範圍 1 n 4000 輸入樣例 7輸出樣例 14因為參加的數可以重複,所以這是乙個完全揹包問題。注意在...

揹包dp 自然數拆分Lunatic版

題意 給定乙個自然數n 1 n 4000 要求把自然數n拆分成n個正整數相加的情況 正整數可以重複出現,但順序不同仍視為同一種情況qaq 求方案數mod 2147483648的值 完全揹包求方案數 又雙叒叕不開long long 見祖宗 1 n可以視為n種物品,每種物品均可無限次使用,揹包容積為n,...

自然數拆分

描述 description 輸入自然數n,然後將其拆分成由若干數相加的形式,參與加法運算的數可以重複。輸入格式 inputformat 輸入只有乙個整數n,表示待拆分的自然數n。n 80 輸出格式 outputformat 輸出乙個數,即所有方案數 樣例輸入 sampleinput 複製資料 7 ...