NYOJ 整數劃分(二)

2021-09-10 01:42:57 字數 1249 閱讀 7894

時間限制:1秒 記憶體限制:128兆

題目描述

把乙個正整數m分成n個正整數的和,有多少種分法?

例:把5分成3個正正數的和,有兩種分法:

1 1 3

1 2 2

輸入第一行是乙個整數t表示共有t組測試資料(t<=50)

每組測試資料都是兩個正整數m,n,其中(1<=n<=m<=100),分別表示要拆分的正數和拆分的正整數的個數。

輸出輸出拆分的方法的數目。

樣例輸入

2

5 25 3

樣例輸出

2

2

分析:把乙個正整數m分成n個正整數的和,求其中的分法。初看此題時,我以為是找規律的思路。後來發現無規律可循,但我們可以從分配方法中找到一些線索,我們先不考慮nm的情況,這種情況下分法為0;當n==1或n==m時分法為1,即只能分為n個1。設分法為sum=dp[m][n],即dp[3][1]=1,dp[10][1]=1......    dp[3][3]=1, dp[5][5]=1.......這些情況不用推就可以理解。那麼,在我們已知n=1的情況下,我們能否遞推出n>1的情況?

試想n=2時,例如dp[5][2],無論怎樣分,肯定有一種分法中包含元素 1 的。我們不妨把包含元素 1 分配情況剔出單獨考慮。既然剔出了 1,m就要變為m-1。同理剔出乙個數,預分配的數量n也要變為n-1,我們就可以先求dp[m-1][n-1]的分配,dp[4][1]=1。考慮完包含元素1的分配情況,我們再單獨考慮不包含元素 1 的情況,既然元素中不包含 1 ,可以看做 (a1+a2+a3+...+am=n && min(ai)>1),我們會發現如果全部ai均減去1,就變成了m-n的n劃分,因為n個數均減1,m就變為了m-n,即dp[m-n][n],我們因此可以求出dp[5][2]不包含1的劃分即dp[3][2].到這裡我們怎麼辦?繼續推!dp[3][2]包含1的部分為dp[2][1]=1 ;不包含1的部分為dp[1][2],因為m歸根到底,對乙個數求其分法時不斷的將其分為包含1的部分和不包含1的部分。最終一定會遇到dp[m][1]或dp[m][n](m=n 或m我們先來一種容易理解的遞迴方法

#includeusing namespace std;

typedef long long ll;

const int m=1e2+5;

ll x,sum,m1,n1;

int dp(int m,int n)

int main()

cin>>x;

while(x--)

}

nyoj整數劃分(二)

時間限制 1000 ms 記憶體限制 65535 kb 難度 3 描述 把乙個正整數m分成n個正整數的和,有多少種分法?例 把5分成3個正正數的和,有兩種分法 1 1 3 1 2 2 輸入 第一行是乙個整數t表示共有t組測試資料 t 50 每組測試資料都是兩個正整數m,n,其中 1 n m 100 ...

NYOJ 整數劃分

時間限制 3000 ms 記憶體限制 65535 kb 難度 3 描述 將正整數n表示成一系列正整數之和 n n1 n2 nk,其中n1 n2 nk 1,k 1。正整數n的這種表示稱為正整數n的劃分。求正整數n的不 同劃分個數。例如正整數6有如下11種不同的劃分 6 5 1 4 2,4 1 1 3 ...

NYOJ 176 整數劃分(二)

整數劃分 二 時間限制 1000 ms 記憶體限制 65535 kb 難度 3 描述把乙個正整數m分成n個正整數的和,有多少種分法?例 把5分成3個正正數的和,有兩種分法 1 1 3 1 2 2 輸入第一行是乙個整數t表示共有t組測試資料 t 50 每組測試資料都是兩個正整數m,n,其中 1 n m...