整数因子分解

整数因子分解问题,是一道很简单的递归题,但是我思考了半天,不知道其一递归结束的条件是什么,其二这个问题应党如何划分。根据给的例子,我是打算去递归处理所给数的每个因子,可我不知道每个因子又该如何递归。所以就卡着不会了。我还想着用动态规划能不能解,想了半天也没想出来,简直是毁心态。搜csdn上有个差不多类型的题目,给了我一点启发,然我在看到答案的时候也学会用画递归树来解决这个问题。
(1)书本上的解答:

void solve(int u){
if(u=1);          //因为是从2枚举到自身,对于指数,就到自身就进入递归最后一层了
totol++;
else{
 for(int i=2;i<=n;i++)
   if(n%i==0) solve(n/i);
} 
}

 这里如果没有学过算数基本定理有点难想。这里贴一下算数分解定理:何一个大于1的自然数 N,如果N不为质数,那么N可以唯一分解成有限个质数的乘积N=P1a1P2a2P3a3......Pnan,这里P1<P2<P3......<Pn均为质数,其中指数ai是正整数。这样的分解称为 N 的标准分解式。
(2)csdn上一位学者的解答,给出了递归和动态规划两种方法
·递归:

int solve(int n){

int ans=1,i;       //ans=1表示n=n的情况
for(int i=2;i<n/i;i++)
if(n%i==0) ans+=solve(i)+solve(n/i);

if(i=n/i) ans+=solve(i);  //因为循环没有取等,这里要特判一下是否开根号也是它的约数
return ans;
}

 这个代码和书本的差不多,无非是以开根号为界限拆成了左半部分和右半部分进行递归。 (3)动态规划

int solve(int n){
  int factor[2000],dp[2000],cnt=0,i;

  //获取n的因子,这里和y总贴出的模板一摸一样
  for(int i=1;i<n/i;i++){
   if(n%i==0)
{
   factor[cnt++]=i;
   factor[cnt++]=n/i;
}
  if(i=n/i) factor[cnt++]=i;

sort(factor,factor+cnt);
fill(dp,dp+cnt,0);

dp[0]=1;  //这里表示第一个因子1的分解式只有它本身
for(int i=1;i<cnt;i++)
 for(int j=0;j<i;j++)
  if(factor[i]%factor[j]==0)
     dp[i]+=dp[j];

return dp[cnt-1];  //因为只有cnt个数,下标从0开始
}

举个很简单的例子,如果n=6 dp[0]=1; //映射因子 1 dp[1]=dp[0]+dp[1]=1; //映射因子 2,2可以分为 2*1 dp[2]=d[0]+dp[2]=1; //映射因子3,3可以分为 3*1 dp[3]=dp[0]+dp[1]+dp[2]+dp[3]=3; //6可以分为 1*6 2*3 3*2 再来解释一下上面的数组含义,factor数组存的是每个数的因子,dp存的是每个因子是否还可以再分解。因为数的所有因子均被列出,根据算数基本定理,n的一个可以被分解的因子分解出来的因子,一定仍然是n的因子,且这个因子比被分解之前小(显然)。由于每个质数因子都有1和它本身,所以就是dp[0]=1,在循环的过程中,质数的dp数组只会被初始化为1,而合数的dp数组则会被拆解。再举个例子,dp[12]第一层循环到4,可以有4=1*4(由dp[0]初始化)和4=2*2由dp[2]初始化。也就是说,每个合数的本身分解(1和自身,而且这个拆解都是由dp[0]转移过来的,而不是dp[本身],内层循环到j=i就终止了,也就是它本身不会与本身作除法)和拆解在循环过程中都会求到。一直转移到我们需要的这个数。

对于递归的话,书上就给我个对每个因子递归搜索就没了。。能不能给我解释一下为何到n==1就停止分解了吗。。
这里贴一张图,理解一下。

这里对每个数分解就递归到自身了,和动态规划有点不同,但好像也差不多。因为没从1开始循环,自身的分解只能靠和自身除了。另外那个循环改为i也是一样的效果,就是对n的每个因子遍历递归。
本以为是很简单的一道题,解答也很简单。没想到思维量这么大,看来不愧是放在最后一道题位置的好题啊。 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值