98 数的划分
作者: Turbo时间限制: 1S章节: 动态规划
问题描述 :
将整数n分成k份,且每份不能为空,任意两份不能相同(不考虑顺序)。
例如:n=7,k=3,下面三种分法被认为是相同的。
1,1,5; 1,5,1; 5,1,1;
问有多少种不同的分法。
样例输入
7 3
样例输出
4 {四种分法为:1,1,5; 1,2,4; 1,3,3; 2,2,3;}
输入说明 :
两个整数n和k
6<n<=200,2<=k<=6
输出说明 :
一个整数,即不同的分法
输入范例 :
7 3
输出范例 :
4
import java.util.Scanner;
public class test_98 {
/**
* 98 数的划分
* dp[i][j]=dp[i-j][1]+dp[i-j][2]+.....+dp[i-j][j]
* dp[i-1][j-1]=dp[i-j][1]+dp[i-j][2]+.....dp[i-j][j-1]
* ->dp[i][j]=dp[i-1][j-1]+dp[i-j][j]
*
* 如果拿到一个整数 i,要求每份不能为空,因此必须先拿出 j 个数位将 j 份分别放上1,此时剩下 i - j个数。
* 那么剩下的数如何处理呢?可以将其全部分到一份当中(dp[i-j][1]),也可以分到两份中(dp[i-j][2]).....
* 也可以分到 j 份中(dp[i-j][j]),而每一种分法都是不相同的,所以可以将其全部加起来,和即为dp[i][j]
*/
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int k = sc.nextInt();
int[][] dp = new int[n+1][k+1];
dp [0][0] = 1;//初态
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= k; j++) {
//盒子数小于苹果数
if(j<=i){
//状态转移方程
dp[i][j]= dp[i-1][j-1]+dp[i-j][j];
}
}
}
System.out.println(dp[n][k]);
}
}