劃分數

題目描述

將整數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;
	}
	
}

有問題請多多指教

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章