问题描述
将整数n分成k份,且每份不能为空,任意两份不能相同(不考虑顺序)。
例如:n=7,k=3,下面三种分法被认为是相同的。
1,1,5; 1,5,1; 5,1,1;
问有多少种不同的分法。
例如:n=7,k=3,下面三种分法被认为是相同的。
1,1,5; 1,5,1; 5,1,1;
问有多少种不同的分法。
输入格式
n,k
输出格式
一个整数,即不同的分法
样例输入
7 3
样例输出
4 {四种分法为:1,1,5;1,2,4;1,3,3;2,2,3;}
数据规模和约定
6<n<=200,2<=k<=6
个人见解:这道题第一次我写了递归的方法,但是我想用动规做一下,然后真成了,对于这道题来说,个人建议用递归,因为这题数字范围并不是很大,下面贴上两种实现代码。
题目传送:数的划分
递归版代码实现
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; public class Main { public static void main(String[] args) throws IOException { BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); String[] s = reader.readLine().split(" "); int n = Integer.parseInt(s[0]),k=Integer.parseInt(s[1]); System.out.println(dfs(1,k,n)); } /** * @param x 代表上一个取出的数,初始值为1 * @param k 代表分成的份数还剩多少份,如果剩1份,种数就是1了 * @param n 表示还剩多大 */ private static int dfs(int x, int k, int n) { if (k==1) { return 1; } int sum = 0; for (int i = x; i <=n/k; i++) { sum+=dfs(i, k-1, n-i); } return sum; } }
dp版代码实现
我的想法:以一个数为基准,逐步减少分割数或减少待分割数这里选取1为基准
得出f[i][j]=f[i-1][j-1]+f[i-j][j](i>=j),f[i][j]=0(i<j).记得f[i][i]=1(范围1-n)
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; public class Main { public static void main(String[] args) throws IOException { BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); String[] s = reader.readLine().split(" "); int n = Integer.parseInt(s[0]); int k = Integer.parseInt(s[1]); int dp[][] = new int[n+1][k+1]; //dp[i][j]表示将i分成j份的方法种数 //初始化:当i=j或j=1的时候,则只有一种分法; for (int i = 1; i <=n; i++) { dp[i][1] = 1; } //当i>j时,我们可以转化为 有1的情况+没有1的情况 //(1)当i>j时 则有dp[i][j] = dp[i-1][j-1]+dp[i-j][j]; //(2)当i=j时 则有1种分法 //(2)当i<j时 则有0种分法 for (int i = 1; i <=n; i++) { for (int j = 1; j <=k; j++) { if (i==j)dp[i][j] = 1; if (i>j)dp[i][j] = dp[i-1][j-1]+dp[i-j][j]; } } System.out.println(dp[n][k]); } }