Problem Description
“Well, it seems the first problem is too easy. I will let you know how foolish you are later.” feng5166 says.
“The second problem is, given an positive integer N, we define an equation like this:
N=a[1]+a[2]+a[3]+…+a[m];
a[i]>0,1<=m<=N;
My question is how many different equations you can find for a given N.
For example, assume N is 4, we can find:
4 = 4;
4 = 3 + 1;
4 = 2 + 2;
4 = 2 + 1 + 1;
4 = 1 + 1 + 1 + 1;
so the result is 5 when N is 4. Note that “4 = 3 + 1” and “4 = 1 + 3” is the same in this problem. Now, you do it!”
Input
The input contains several test cases. Each test case contains a positive integer N(1<=N<=120) which is mentioned above. The input is terminated by the end of file.
Output
For each test case, you have to output a line contains an integer P which indicate the different equations you have found.
Sample Input
4
10
20
Sample Output
5
42
627
题意是将一个整数N分解为不大于N的各个整数和的形式的个数。
这里使用动态规划来完成。dp[i][j]为将i分解为不大于j的个数。
import java.util.Arrays;
import java.util.Scanner;
public class P1027 {
int[][] dp = new int[130][130];
public static void main(String[] args) {
new P1027().run();
}
public void run(){
Scanner scanner = new Scanner(System.in);
int n;
while (scanner.hasNextInt()) {
n = scanner.nextInt();
for (int i = 0; i <= n; i++) {
Arrays.fill(dp[i], -1);
}
System.out.println(calc(n, n));
}
scanner.close();
}
//dp[i][j]表示 i 表示成最大的数不超过 j 的方法数
int calc(int n, int m){
if(dp[n][m] != -1)
return dp[n][m];
if(n < 1 || m < 1)
return dp[n][m] = 0;
if(n == 1 || m ==1)
return dp[n][m] = 1;
if(n < m)
return dp[n][m] = calc(n, n);
if(n == m)
return dp[n][m] = calc(n, m - 1) + 1;
//dp[n][m]由不包括m的数字组成的n和包括m组成n的个数
return dp[n][m] = calc(n, m - 1) + calc(n - m, m);
}
}
注:提交到OJ上,请将主类名改为Main。