将计算出的不同的分解式数。
输入 输出
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;
}