给定一个正数1,裂开的方法有一种,(1)
给定一个正数2,裂开的方法有两种,(1和1)、(2)
给定一个正数3,裂开的方法有三种,(1、1、1)、(1、2)、(3)
给定一个正数4,裂开的方法有五种,(1、1、1、1)、(1、1、2)、(1、3)、(2、2)、 (4)
给定一个正数n,求裂开的方法数。
import java.util.Scanner;
public class Main {
public static int ways1(int n) {
if (n < 1) {
return 0;
}
return process(1, n);
}
public static int process(int pre, int rest) {
if (rest == 0) {
return 1;
}
if (pre > rest) {
return 0;
}
int ways = 0;
for (int i = pre; i <= rest; i++) {
ways += process(i, rest - i);
}
return ways;
}
/**
* 未使用优化的dp版本
*/
private static int solveDp(int n) {
int[][] dp = new int[n + 1][n + 1];
for (int i = 1; i <= n; ++i) {
dp[i][0] = 1;
}
for (int i = n; i >= 1; i--) {
for (int j = i; j <= n; j++) {
for (int k = i; k <= j; ++k) {
dp[i][j] += dp[k][j - k];
}
}
}
return dp[1][n];
}
/**
* 优化后的dp
* 斜率优化
*/
private static int solveDpPlus(int n) {
int[][] dp = new int[n + 1][n + 1];
for (int i = 1; i <= n; ++i) {
dp[i][0] = 1;
}
dp[n][n] = 1;
for (int i = n - 1; i >= 1; i--) {
for (int j = i; j <= n; j++) {
// dp[i][j - i] + dp[i+1][j-i-1]+dp[i+2][j-i-2]+...+dp[j][0]
dp[i][j] = dp[i + 1][j] + dp[i][j - i];
}
}
return dp[1][n];
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
while (in.hasNext()) {
int n = in.nextInt();
int solve = solveDpPlus(n);
int trueRet = ways1(n);
if (solve != trueRet) {
System.out.println("xxxxxx");
}
System.out.println(solve);
}
}
}