数论:正整数分解使得乘积最大


引入问题:

要求将一个正整数n分成几个自然数的和,使这些自然数的乘积最大。输出这个最大值。
分两种要求:

(1)这些自然数可以相同;
(2)这些自然数互不相同;

(同一个数n,1的结果应该比2大)。



分析:
(只分析n>=4的情况,因为n<4最大值都是本身)

1.这些自然数可以相同

我们先列几个数找找规律:
4=2+2、5=3+2、6=3+3、7=3+2+2、8=2+2+2+2、9=3+3+3、10=2+2+2+2+2 …

观察这些数可以得如下规律:

(1)拆分的自然数不会超过3,因为4可以化为2+2,5可以化为3+2>5,所以所有的数都可以拆为只 有3和2的数;
(2)因为都可以拆除3和2,所有为了使乘积大,应该先尽可能拆除3,而后拆除2,分成1无贡献;


那么我们考虑所有的n除以3的情况:

  1. 可以被3整除,那么就将他全部拆为3,如:9=3+3+3;
  2. 被3除余1,那么可以拆为形如3+3+……+3+4,即3+3+……+3+2+2,如10=3+3+2+2;
  3. 被3除余2,那么可以拆为形如3+3+……+3+2,如11=3+3+3+2;

实现代码:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
int t,n;
int main()
{
    scanf("%d",&t);
    while(T--)
    {
    	scanf("%d",&n);
        int ans;
        if(n<4) ans=n; 
        else
        {
          	int cnt3,cnt2; // 3的个数 2的个数
            if(n%2==1) // n为奇数
            {
                cnt3=(n-3)/6*2+1;
                cnt2=(n-3)%6/2;
            }
            else // n为偶数
            {
                cnt3=n/6;
                cnt2=n%6/2;
            }
            ans=pow(3,cnt3)*pow(2,cnt2);
        }
        printf("%d\n",ans);
    }
    return 0;
}



2.这些自然数互不相同

也是先写几个数找规律:
5=2+3、6=2+4、7=3+4、8=3+5、9=2+3+4、10=2+3+5、11=2+4+5、12=3+4+5、13=3+4+6、
14=2+3+4+5、15=2+3+4+6、16=2+3+5+6、17=2+4+5+6、18=3+4+5+6……
(其实不用列数字,凭以往经验也应该知道,如果互不相同,这些自然数应该尽量连续,才能使乘积大)

我们可以发现如下规律:

  • 数字应该尽量连续,而且应该从2开始(因为1不做贡献,分1不如把一加在后面的数上)

下面对连续自然数做出分析:
我们可以得到形如:2+3+4+5+……k的式子,n是任意整数,我们并不能才好得到连续的自然数,可能多出△x。
对应△x我们可以保证他0<=△x<=k(为什么一定小于等于k?因为如果大于k,原式应该多加一项变成2+3+4+……+k+k+1)

那么多出来的△x应该怎么处理,有上面列的几个式子的规律,显然应该从后往前均摊给前k-1个数。
为什么从后往前呢?应该从前往后或遇到重复的数。

那么当我们分完△x后,应该会得到两种式子:

  1. △x=k 3+4+5+6+……+k+(k+2)
  2. △x<k 2+3+4+……+(k-△x)+(k-△x+1)+……+(k+1)

显然我们要求出式子的值,应该借助阶乘,阶乘中缺失的项,我们除掉就好了,如果数值要求大要求取模,就要用到除法逆元了。求阶乘可以用前缀积,连续自然数则用前缀和,如果时间要求有现在,就用二分来优化,二分找最接近n的前缀和。


这里推荐一个题目:HDU 5976
(这题就用到了逆元,和二分)

题解

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: A: ```python def factorize(num): factors = [] divisor = 2 while divisor <= num: if num % divisor == 0: factors.append(divisor) num /= divisor else: divisor += 1 result_str = str(factors[0]) for i in range(1, len(factors)): result_str += "*" + str(factors[i]) return "{}={}".format(num, result_str) # 测试 print(factorize(90)) ``` 输出: ``` 1=[2*3*3*5] ``` 注:这里的返回值是用字符串表示的分解结果。 ### 回答2: 要将一个整数分解质因数,可以采用如下步骤: 1. 首先,定义一个变量num,表示要分解的整数。 2. 初始化一个空列表factor_list,用于存储分解后的质因数。 3. 创建一个for循环,不断遍历2到num之间的所有整数。 4. 在循环中,判断当前整数i是否能够整除num。 - 如果能够整除,将i添加到factor_list中,并将num除以i的结果重新赋值给num。 - 如果不能整除,跳过当前循环。 5. 当循环结束时,判断num是否为1,如果不为1,则说明num本身就是一个质数,则将num添加到factor_list中。 6. 最后,将num和factor_list打印出来,格式为"输入的整数=质因数1*质因数2*..."。 下面是一个示例代码: ```python num = int(input("请输入一个整数:")) factor_list = [] for i in range(2, num + 1): while num % i == 0: factor_list.append(i) num /= i if num > 1: factor_list.append(num) print("输入的整数 =", "*".join(map(str, factor_list))) ``` 例如,当输入90时,输出为"输入的整数 = 2*3*3*5"。这表示90可以分解为2乘以3乘以3乘以5。 ### 回答3: 要将一个整数分解质因数,首先需要找到它的最小质因数。然后,我们可以将该质因数除到无法再整除为止。具体步骤如下: 1. 输入一个整数,如90。 2. 从最小的质数2开始,判断该数是否能被2整除。在该例中,90可以被2整除,所以我们将2作为90的一个质因数。 3. 将90除以2,得到45。再次判断45是否能被2整除,答案是不可以。 4. 接下来,我们从3开始判断45是否能被3整除。在该例中,45可以被3整除,所以我们将3作为45的一个质因数。 5. 将45除以3,得到15。再次判断15是否能被3整除,可以得出答案是可以。 6. 重复以上步骤,我们得到15除以3的结果是5。5是一个质数,所以我们将5作为15的一个质因数。 7. 由于5已经是一个质数,无法再分解,所以我们停止计算。 8. 综上所述,90可以分解质因数为2 * 3 * 3 * 5。 这个方法适用于任何整数,可以得到它的所有质因数分解形式。质因数分解在数论和代数方面起着重要的作用,可以帮助我们更好地理解数的性质。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值