[解题报告]《算法零基础100讲》(第10讲) 因子分解和枚举(下)

简介: [解题报告]《算法零基础100讲》(第10讲) 因子分解和枚举(下)

零、写在前面


        这是打卡的第十天,由于今天的第二题有一定的难度,需要我花费比较大的篇幅做题解,这是第二篇,主要讲解第三题。我增加了一道题作为这道题的第一步辅助理解。上一篇在


[解题报告]《算法零基础100讲》(第10讲) 因子分解和枚举(上)https://blog.csdn.net/qq_17593855/article/details/121052656

https://blog.csdn.net/qq_17593855/article/details/121052656


一、预备知识


⚠这部分不是特别难,只要你能理解,你就可以很容易的写这道题


整数拆分


       给定一个正整数 n,将其拆分为至少两个正整数的和,并使这些整数的乘积最大化。 返回你可以获得的最大乘积。


       最简单的方式肯定是穷举所有可能算最大成绩,但是这种东西一看就是会有结论的,我们何不推一推呢?


         根据高中数学知识我们知道柯西不等式,几何平均大于等于调和平均:


                              image.png


       这道题已知的是image.png 要求的是 image.png 的最大值不妨记为image.png


       易知 image.png


       也就是image.png


       对右边求导我们得到image.png 所以我们可以知道当n/x = e 的时候函数取最大值。但是原题只让我们分解为正整数,我们知道e大约是2.7左右,所以我们把n分解为尽量多的3时函数可以取到最大值。但是当最后只剩1的时候需要和前面一个三合并拆成两个2这样最大。(因为柯西告诉我们这些数相差越小乘积越大 其实4也需要验证 但是4 =2 x 2所以没差啦)


if(n == 1)    return 1;
    if(n % 3  == 0) return pow(3,n/3);
    else if(n % 3 == 1) return pow(3,n /3 -1)*4;
    else return pow(3,n/3)*2;

       结果是不是很简洁?这个其实记得住把?记不住过程请记住结论。可以试试我给的习题一练习一下。


二分快速幂


       这道题还需要知道这个知识点,不然的话会超时。。。


       首先有一个引论 image.png


       其实就是积对一个数取余等于两个数分别取余然后乘积再对c取余


       证明其实很简单  假如a = X1x c+Y1,b = X2 x c +Y2


       就可以得到ab = (X1 x X2Y1 +X1Y2 + X2)x c + Y1 x Y2        这里结论是不是很显然?


       然后我们做一点点推广可以得到这样的递推式image.png


      利用上面的结论得到:image.png


       我们把它做成一个函数形式就是


long long f(long long a, long long b, long long c) {
    if (b == 0)
        return 1 % c;
    long long v = f(a*a % c, (b>>1), c);
    if (b & 1)
        v = v * a % c;
    return v;
}     

注:>>1与/2是没有任何区别的,完全和上面的递推式相同,目的就是为了二分减小b的值快速得到答案。

二、课后习题详解


整数拆分


343. 整数拆分

https://leetcode-cn.com/problems/integer-break/


       给定一个正整数 n,将其拆分为至少两个正整数的和,并使这些整数的乘积最大化。 返回你可以获得的最大乘积。


思路


       上面讲的结论用一用就好了嘛,不然真去拆分?但是这里说明了至少两个所以需要对1、2、3单独去判断。

int integerBreak(int n){
    if(n == 1 || n == 2)    return 1;
    if(n == 3) return 2;
    if(n % 3  == 0) return pow(3,n/3);
    else if(n % 3 == 1) return pow(3,n /3 -1)*4;
    else return pow(3,n/3)*2;
}


结果分析


image.png


       无敌,也是一种淡淡的忧伤~


好因子的最大数目


1808. 好因子的最大数目

https://leetcode-cn.com/problems/maximize-number-of-nice-divisors/


       给你一个正整数 primeFactors 。你需要构造一个正整数 n ,它满足以下条件:


  • n 质因数(质因数需要考虑重复的情况)的数目 不超过 primeFactors 个。
  • n 好因子的数目最大化。如果 n 的一个因子可以被 n 的每一个质因数整除,我们称这个因子是 好因子 。比方说,如果 n = 12 ,那么它的质因数为 [2,2,3] ,那么 6 和 12 是好因子,但 3 和 4 不是。

       请你返回 n 的好因子的数目。由于答案可能会很大,请返回答案对 109 + 7 取余 的结果。


       请注意,一个质数的定义是大于 1 ,且不能被分解为两个小于该数的自然数相乘。一个数 n 的质因子是将 n 分解为若干个质因子,且它们的乘积为 n 。


思路


       一共n个质因数,好因子其实就是质因子的乘积得到的,比如例子给的2,2,3有三个质因数,其中两个不相同,最终的好因子数就是2x1。易知如果一个数的质因数为则所有的好因子数目就是k·q·w个。这么来看的话和前面的整数是不是就是一样的了?


       直接利用相关的结论就好了,但是这题的数据量太大了,如果直接计算会超时并且会上溢出。所以要用二分快速幂。


long long f(long long a, long long b, long long c) {//二分快速幂 讲过了。。告辞
    if (b == 0)
        return 1 % c;
    long long v = f(a*a % c, (b>>1), c);
    if (b & 1)
        v = v * a % c;
    return v;
}
int maxNiceDivisors(int primeFactors){//这里就是把上面的整数拆分的计算换一种方式 其它一样。
if(primeFactors == 1) return 1;
    long long ans = 1;
    if(primeFactors % 3 == 0){
        ans = f(3,primeFactors / 3,1000000007);
    }
    else if(primeFactors % 3 == 1) {
        ans = f(3,primeFactors / 3 - 1 ,1000000007);
        ans = (ans*4)%(1000000007);
    }
    else{
        ans = f(3,primeFactors / 3,1000000007);;
        ans = (ans*2)%(1000000007);
    }
    return ans;
}


结果分析


image.png


在非人的领域,同样无敌~


课后总结


之前有人说说有问题都是数学,我不信。


今天我信了。。。


加油 一起学习!


相关文章
|
6月前
|
算法 Java C语言
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-246 算法训练 猴子吃包子
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-246 算法训练 猴子吃包子
64 2
|
6月前
|
算法 Java C语言
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-48 算法训练 关联矩阵
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-48 算法训练 关联矩阵
66 0
|
6月前
|
算法 Java C语言
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-42 算法训练 送分啦
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-42 算法训练 送分啦
59 0
|
6月前
|
算法 Java C语言
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-8 算法训练 操作格子 线段树
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-8 算法训练 操作格子 线段树
55 0
|
6月前
|
算法 Java Serverless
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-444 算法训练 求和问题
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-444 算法训练 求和问题
56 1
|
6月前
|
算法 Java C语言
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-439 算法训练 简单字符变换
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-439 算法训练 简单字符变换
54 1
|
6月前
|
人工智能 算法 Java
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-7 算法训练 逆序对 平衡二叉树
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-7 算法训练 逆序对 平衡二叉树
56 0
|
6月前
|
算法 Java C语言
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-49 算法训练 寻找数组中最大值
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-49 算法训练 寻找数组中最大值
52 0
|
1月前
|
算法 Java 程序员
【算法每日一练及解题思路】有n级台阶,一次只能上1级或2级,共有多少种走法?
本文深入解析了“爬楼梯问题”,探讨了递归与迭代两种解法,并提供了Java代码实现。通过分析问题本质,帮助读者理解动态规划技巧,提高解决实际编程问题的能力。关键词:Java, 算法, 动态规划, 爬楼梯问题, 递归, 迭代。
68 0
|
1月前
|
算法 C++
【算法解题思想】动态规划+深度优先搜索(C/C++)
【算法解题思想】动态规划+深度优先搜索(C/C++)