AcWing 900 整數劃分

2021-10-02 04:38:00 字數 1463 閱讀 7180

題目描述:

乙個正整數n可以表示成若干個正整數之和,形如:n=n1+n2+…+nk,其中n1≥n2≥…≥nk,k≥1。

我們將這樣的一種表示稱為正整數n的一種劃分。

現在給定乙個正整數n,請你求出n共有多少種不同的劃分方法。

輸入格式

共一行,包含乙個整數n。

輸出格式

共一行,包含乙個整數,表示總劃分數量。

由於答案可能很大,輸出結果請對10^9+7

取模。資料範圍

1≤n≤1000

輸入樣例:

5
輸出樣例:

7
分析:

本題要求我們對整數進行劃分,且次序不重要,也就是說1 2 3與3 2 1被視為一種劃分方案。正整數n,可以劃分為若干個1,若干個2,...。

方法一:

類似於完成揹包問題,每個數可以選無限次,但是總和不能超過n,不同的是,完全揹包問題是求選法中最小的代價,而整數劃分是要求劃分總的方案數。設f[i][j]表示在1到i中選出總和為j的方案數,則數字i可以選擇0到k次,f[i][j] = f[i-1][j] + f[i-1][j - i] + ... + f[i-1][j-ki],j >= ki。又f[i][j - i] = f[i - 1][j - i] + f[i-1][j-2i] + ... + f[i-1][j-ki],從而f[i][j] = f[i][j-i] + f[i-1][j]。使用滾動陣列實現得到狀態轉移方程為f[i] = f[j-i] + f[i]。

#include #include using namespace std;

const int maxn = 1005,mod = 1e9 + 7;

int f[maxn];

int main()

}cout《方法二:

f[i][j]表示總和為i,劃分為了j個數的方案數。狀態劃分可標識為這j個數中是否包含了1;如果包含1,則f[i][j] = f[i-1][j-1],即方案數等於去掉乙個1後的方案數,j - 1個數總和是i - 1;如果這j個數中不包含1,則f[i][j] = f[i - j][j],即方案數等於將j個數每個都減去1後構成總和為i - j的方案數。因此可以得到狀態轉移方程為f[i][j] = f[i-1][j-1] + f[i-j][j]。最後的解為f[n][1] + ... + f[n][n],即所有能構成總和是n的劃分方案的和。

#include #include using namespace std;

const int maxn = 1005,mod = 1e9 + 7;

int f[maxn][maxn];

int main()

}int res = 0;

for(int i = 1;i <= n;i++) res = (res +f[n][i]) % mod;

cout

}

Acwing 900 整數劃分

乙個正整數n可以表示成若干個正整數之和,形如 n n1 n2 nk,其中n1 n2 nk,k 1。我們將這樣的一種表示稱為正整數n的一種劃分。現在給定乙個正整數n,請你求出n共有多少種不同的劃分方法。輸入格式 共一行,包含乙個整數n。輸出格式 共一行,包含乙個整數,表示總劃分數量。由於答案可能很大,...

AcWing 1603 整數集合劃分(簡單貪心)

題目鏈結 給定乙個包含 n 個正整數的集合,請你將它們劃分為兩個不相交的集合 a1 和 a2,其中 a1 包含 n1 個元素,a2 包含 n2 個元素。用 s1 表示集合 a1 內所有元素之和,s2 表示集合 a2 內所有元素之和。請你妥善劃分,使得 n1 n2 盡可能小,並在此基礎上 s1 s2 ...

整數劃分(劃分dp)總結

寫了幾個題發現整數劃分是一類題,而不是一道題。具體題型 1 n相同元素放入m個相同的盤子 盤子允許為空 例題 放蘋果 poj 1664設dp i j 為 j 個元素放入i個盤子轉移方程 dp i j dp i 1 j 新新增乙個盤子,盤子為空 dp i j dp i j i i個盤子 各取出乙個 2...