DP GDOI2013 整數分拆

2021-06-21 20:39:12 字數 1174 閱讀 4495

【題目大意】整數分拆問題是指將乙個正整數寫成若干正整數之和有多少種不同的分法的問題。

通過新增不同的限制,如正整數的個數,每個正整數的大小限制,我們可以得到不同的整數拆分問題。

在本問題中,給定n(被分拆的整數)和k(拆成的整數的個數),你需要求滿足以下k個條件的整數拆分的方案數:

1、a1+a2+...+ak=n

2、a1*b1<=a2

3、a2*b2<=a3

...k、a(k-1)*b(k-1)<=ak

【題解】

我們令a2=a1*

b1+x1,a3=a2*b2+x2,a4=a3*b3+x3……

迭代化簡後,我們可以根據這個僅用xi和a1表示所有的a。

我們先把a1,x1,x2,x3...的係數都算出來。

問題轉化成:已知係數k,k1,k2...

求:a1*k+x1*k1+x2*k2+... = n的方案數(注意:需要滿足a1>=1,xi>=0)

用f[i][j]表示第i個數當前和為j的方案數

則有,f[i][j] = sigma

我們發現f[i][j]比f[i][j-ki]只是多加了乙個f[i-1][j]

所以可以消去一維,用f[j]表示第i個數當前和為j的方案數。

則有:

外層列舉i

內層:for (int j = ki;j <= n;j ++) f[j] = f[j] + f[j-ki]

#include#include#define fo(i,a,b) for (int i = a;i <= b;i ++)

using namespace std;

const int maxn = (int)1e5 + 5;

const int p = (int)1e9 + 7;

int t,n,k,f[maxn],b[maxn],k[maxn];

int main()

} int ans = 0;

memset(f,0,(n+1)*4);

f[0] = 1;

fo(i,2,k) fo(j,k[i],n) f[j] = (f[j] + f[j-k[i]]) % p;

fo(a1,1,n)

printf("%d\n",ans);

} return 0;

}

正整數分組

將一堆正整數分為2組,要求2組的和相差最小。例如 1 2 3 4 5,將1 2 4分為1組,3 5分為1組,兩組和相差1,是所有方案中相差最少的。整數個數n 100,所有整數的和 10000 初看題目,第一想到貪心。怎麼貪?排序,每次把數放到 最有利 的一邊,最有利指的是每次都把數放到使得結果差值盡...

正整數分組

將一堆正整數分為2組,要求2組的和相差最小。例如 1 2 3 4 5,將1 2 4分為1組,3 5分為1組,兩組和相差1,是所有方案中相差最少的。input 第1行 乙個數n,n為正整數的數量。第2 n 1行,n個正整數。n 100,所有正整數的和 10000 output 輸出這個最小差 samp...

正整數分組

將一堆正整數分為2組,要求2組的和相差最小。例如 1 2 3 4 5,將1 2 4分為1組,3 5分為1組,兩組和相差1,是所有方案中相差最少的。整數個數n 100,所有整數的和 10000 初看題目,第一想到貪心。怎麼貪?排序,每次把數放到 最有利 的一邊,最有利指的是每次都把數放到使得結果差值盡...