給定乙個自然數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 ...