整数因子分解问题

整数因子分解问题 
´问题描述: 
大于1 的正整数n 可以分解为:n=x1 *x 2*…*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 共有多少种不同的分解式。 
´数据输入: 
输入数据第一行有1 个正整数n (1≤n≤2000000000) 。 
´结果输出: 

将计算出的不同的分解式数。 

输入                          输出
                         
 12                              8 

递归解法01:

显然当n等于2000,000,000时递归栈溢出

#include <cmath>
#include <cstdio>
#include <algorithm>
#include <iostream>
using namespace std;

int cnt,n;
void f(int n)
{
	if(n==1)
		cnt++;
	for(int i=2;i<=n;i++)
	{
		if(n%i==0)
			f(n/i);
	}
}
int main()
{
	scanf("%d",&n);
	f(n);
	cout<<cnt<<endl;
	return 0;
} 

dp解法02:
递归算法与非递归算法的转化
#include <cmath>
#include <cstdio>
#include <algorithm>
#include <iostream>
using namespace std;

/*
递归方程(即递推式,动态方程) 
h(n)为n的划分数
h(1) = 1
h(n) = h(n/2) + h(n/3) + ... + h(n/n)  	 前提是能被整除即 
     = h(x1)+h(x2)+...+h(xj)   			x1,x2,...,xj都是n的因子 
 */
int a[10005],k;	//数组a保存n的因子,k为a数组最后一位因子的下一位所值的地方(下标) 
int h[10005];	//保存结果 
int n;
void divisor(int n)	//求n的因子,杂度为O(sqrt(N)). 
{
	int i; 
	for(i=1;i<sqrt(n);i++) //i<sqrt(n)等价与i*i<n 
	{
		if(n%i==0)
		{
			a[k++]=i;
			a[k++]=n/i;
		}
	}
	if(i*i==n) //处理因子相同,且只可能出现在i*i==n(即i=sqrt(n))处 
		a[k++]=i;
}
int solve()
{
	h[0]=1;	//初始 
	for(int i=1;i<k;i++)	//i保存的下标,a[i]->a[k-1]
	{
		for(int j=0;j<i;j++) //j保存的也是下标 a[0]->a[i-1](所以j<i)
		{
			if(a[i]%a[j]==0)	
			{
				h[i]+=h[j];
			}
		}
	}
	return h[k-1];
}
int main()
{
	scanf("%d",&n);
	divisor(n);
	sort(a,a+k);	//让因子从小到大排序 
	cout<<solve()<<endl;;
	return 0;
}



你可能感兴趣的:(算法,递归,动态规划DP)