題目描述
將整數n分成m份,求劃分的種數,注意每份不爲空,不考慮順序。 比如整數4的劃分,1 1 2 和 1 2 1 以及2 1 1 爲同一種劃分。
輸入格式:
多組測試樣例,每組兩個整數。n和m。(6<n<=200,2<=m<=6)
輸出格式:
每組測試樣例輸出一行。輸出一個整數表示劃分的種數。
輸入樣例
7 3
輸出樣例
4
說明
7的劃分有{1,1,5;1,2,4;1,3,3;2,2,3}
這道題百度了一下網上基本就給了一個公式沒有解釋,然後沒想出來他們的遞推原理,我一直知道必須通過遞推寫,但是找不到規則就用循環寫,小的用例能得到答案,但是大數用例就不行了,然後我就問了一下大佬,他解釋了一遍總算明白dp的原理,稍作解釋:
其實就是劃分的時候有兩種情況
- 劃分出來的第一份有1的情況,例如:1,1,5;1,2,4;1,3,3;,此時就可以刪除第一份的1,就是總數-1然後分數也-1,那麼含有1的數量就是dp[i-1][j-1],
- 劃分出來的第一份不含有1即大於1的情況,例如:2,2,3,此時可以將每份都-1,份數不變,即爲dp[i-j][j];
- 最終得出dp[i][j] = dp[i-1][j-1]+dp[i-j][j];
代碼如下
#include<iostream>
#include<stdio.h>
using namespace std;
main()
{
int m,n,sum=0;
int dp[202][7]={0};
dp[1][1]=1;
for(int i=2;i<=200;i++){;
for(int j=1;j<=6;j++){ //只要dp前6個就行
dp[i][j]=dp[i-1][j-1]+dp[i-j][j];
}
}
while(scanf("%d%d",&m,&n)!=EOF){
cout<<dp[m][n]<<endl;
}
}
有問題請多多指教