2-14 整数因子分解问题
问题描述
大于1的正整数n可以分解为:n=x1∗x2∗…∗xmn=x1∗x2∗…∗xm。例如,当n=12 时,共有8 种不同的分解式:
12=12;
12=6*2;
12=4*3;
12=3*4;
12=3*2*2;
12=2*6;
12=2*3*2;
12=2*2*3。
对于给定的正整数n,计算n共有多少种不同的分解式。
分析
设h(n)为n的划分数
h(1) = 1
h(2) = 1
h(n)=h(n/2)+h(n/3)+...+h(n/n)h(n)=h(n/2)+h(n/3)+...+h(n/n) (前提是能被整除)
递归
Java
import java.util.Scanner;
public class ZhengShuYinZiFenJie {
private static int total=0;
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int n;
while(true){
//还原初始值
total = 0;
n = input.nextInt();
recursive(n); //递归调用
System.out.println(total);
System.out.println("-------------");
}
}
private static void recursive(int n){
if(n == 1)
total++;
else
for(int i=2; i<=n; i++)
if(n%i == 0)
recursive(n/i);
}
}
Input & Output
12
8
-------------
12
8
-------------
3
1
-------------
4
2
-------------
5
1
-------------
1
1
-------------
56
20
-------------
56
20
-------------
66
13
-------------
67
1
-------------
动态规划
Java: version 1
import java.util.Scanner;
public class ZhengShuYinZiFenJie1 {
private static int total=0;
private static int[] h = new int[10000];
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int n;
while(true){
//还原初始值
total = 0;
h = new int[10000];
n = input.nextInt();
total = dynamic(n);
System.out.println(total);
System.out.println("---------------");
}
}
//动态规划
private static int dynamic(int n){
h[1] = 1;
h[2] = 1;
for(int i=3; i<=n; i++)
for(int j=2; j<=i; j++)
if(i%j == 0) //如果j能被i整除
h[i] += h[i/j];
return h[n];
}
}
Input & Output
12
8
---------------
12
8
---------------
3
1
---------------
4
2
---------------
1
1
---------------
56
20
---------------
Java: version 2
import java.util.Arrays;
import java.util.Scanner;
public class ZhengShuYinZiFenJie2 {
private static int[] divisors; //保存n的因子,k为a数组最后一位因子的下一位所值的地方(下标)
private static int[] h; //保存结果
private static int n;
private static int k; //k为divisors数组最后一位元素的下一位(下标)
private static int total;
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
while (true){
k = 0;
h = new int[1005];
divisors = new int[1005];
n = input.nextInt();
divisor(n);
Arrays.sort(divisors, 0, k);
total = dynamic();
System.out.println(total);
System.out.println("---------------");
}
}
private static int dynamic(){
h[0]=1; //初始
for(int i=1; i<k; i++){
for(int j=0; j<i; j++){
if(divisors[i]%divisors[j] == 0){
h[i] += h[j];
}
}
}
return h[k-1];
}
private static void divisor(int n){
int i;
for(i=1; i<Math.sqrt(n); i++){
if(n%i == 0){
divisors[k++] = i;
divisors[k++] = n/i;
}
}
if(i*i == n) //处理因子相同,且只可能出现在i*i==n(即i=sqrt(n))处
divisors[k++] = i;
}
}
Input & Output
12
8
---------------
12
8
---------------
3
1
---------------
4
2
---------------
66
13
---------------
Reference
王晓东《计算机算法设计与分析》(第3版)P47

这篇博客介绍了如何解决整数因子分解问题,详细阐述了问题描述,通过递归和动态规划两种方法进行分析。递归部分提供了Java实现,并展示输入输出示例。动态规划部分同样包含两个Java版本的代码,同样配有输入输出示例。
2356

被折叠的 条评论
为什么被折叠?



