题目
有一个正整数 n,如果存在 n1 + n2 + ... + nk = n (nk > 0),则称 {n1, n2, ..., nk} 为正整数 n 的一个划分
问正整数 n 一共有多少个划分?
输入描述
一个正整数 n
输出描述
输出一个整数,表示 n 一共有多少个划分
样例输入
6
样例输出
11
代码
import java.util.Scanner;
/**
* 例如正整数 6 有如下 11 种划分
* 6
* 5 1
* 4 2 4 1 1
* 3 3 3 2 1 3 1 1 1
* 2 2 2 2 2 1 1 2 1 1 1 1
* 1 1 1 1 1 1
* 设 p(n, m) 为正整数 n 的所有划分中最大加数小于等于 m 的划分数
* 则可以分为如下四种情况进行讨论:
*
* (1) 当 n == 1 或者 m == 1 的时候,f(n, m) = 1
*
* (2) 当 n == m 时,f(n, m) = f(n, m - 1) + 1
* 因为在 n 的所有划分中,最大加数为 n 时,只有一种划分,即 {n}
* 所以,f(n, m) 就等于最大加数为 m - 1 的划分数加 1
*
* (3) 当 n < m 时,f(n, m) = f(n, n)
* 因为在 n 的所有划分中,最大加数只能小于等于 n
*
* (4) 当 n > m 时,f(n, m) = f(n, m - 1) + f(n - m, m)
* f(n, m - 1) 为最大加数小于等于 m - 1 的划分数
*
* 当最大加数为 m 时,那么每个划分序列有了一个 m,还差 n - m
* 就相当于是 n - m 有多少个最大加数小于等于 m 的划分数,即 f(n - m, m)
*
* 这两部分之和就等于 f(n, m)
*/
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt(), m = scanner.nextInt();
System.out.println(split(n, m));
}
private static int split(int n, int m) {
if (n == 1 || m == 1)
return 1;
else if (n == m)
return split(n, n - 1) + 1;
else if (n < m)
return split(n, n);
else
return split(n, m - 1) + split(n - m, m);
}
}