题目描述
将整数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;
}
}
有问题请多多指教