【贪心法】最优分解问题

简介: 【贪心法】最优分解问题

 题目描述:

问题描述:

  设n 是一个正整数。现在要求将n 分解为若干个互不相同的自然数的和,且使这些自然数的乘积最大。

编程任务:

  对于给定的正整数n,编程计算最优分解方案。

数据输入:

  (由文件input.txt 提供输入数据。)文件的第1 行是正整数n。

结果输出:

  程序运行结束时,将计算出的最大乘积输出(到文件output.txt 中)

输入文件示例         输出文件示例

input.txt            output.txt

10                 30

注:若上述题目要求有括号中橙色字体,即将代码中第7,8行注释解除,令其执行即可。

算法思路:

一、主体思路须知:

(1)、两数和一定时,两数相差越小,两数乘积越大

(2)、将数分解时,应尽可能使分解的因子没有1。因为1*2*3<2*4。(两者和为6)

由于此条,所以n要分类讨论。n<=4时,除了n=2(不能分解),其余分解必须含因子1。

二、分类讨论:

1、n=1,输出1

2、n=2,输出2

3、n=3,输出1*2=2

4、n=4,输出1*3=3

5、n>=5,执行主体代码部分

三、对n>=5,主题代码部分解释:

       由于两数和一定时,两数相差越小,两数乘积越大。

       (1)因此从因子2开始分解,即分解为因子2、3、4……

       (2)直至n减去“已分解的因子和”的结果(即代码中的OneSum)小于已分解的最大因子。

       (3)然后在n已分解的因子中,从最大到小,依次+1(执行OneSum次)

       (4)OneSum恰巧等于分解的最后一个因子时,因为此分解法为2、3……,会导致数组存储的因子全加1后,还剩余1,所有需要用“if(i==-1) {i=flag;}”来将i赋值到数组存储数据的末尾,继续+1,下方示例中注释有详细解释。

       例n=11:

       第一波分解结果:2,3,4。余2(余数OneSum=2小于已分解的最大因子4)。

       第二波操作:将4(最大因子)+1,3(第二大因子)+1

                            结果:2,4,5。(即从最大因子到小因子,依次+1(执行OneSum=2次))

       第三波操作:计算2*4*5=40,40即n=11分解的不同自然数因子取得的最大乘积。

代码如下:

#include <iostream>
#include <fstream> //文件操作头文件 
using namespace std;
#define N 10000
int main(){
  //freopen("input.txt","r",stdin);
  //freopen("output.txt","w",stdout);
  int n;cin>>n;
  int a[N];
  if(n==1) cout<<1<<endl;
  else if(n==2) cout<<2<<endl;
  else if(n==3) cout<<2<<endl;
  else if(n==4) cout<<3<<endl;
  else{//n>=5时 
    int num=2; n=n-num;//首先存入2 (1计入因子中,乘积较小,例如1*2*3<2*4)
    int i=0; a[i]=num; 
    int OneSum=0;//记录n减去数组中存储的不同自然数总和的结果 
    while(n>a[i]){//注:while是先判断,再执行 
      num++;i++;//已经存了2,所以先各+1 
      a[i]=num;
      OneSum=n=n-num;   
    }
    int flag=i; int OutNum=1;//存储因子乘积,输出是乘积结果,初始值为1 
    while(OneSum>0){//将因子数组从后往前 OneSum个数皆+1 
      a[i]=a[i]+1;
      OneSum=OneSum-1;
      i--;
      if(i==-1) {i=flag;} 
       //新补加条件, 例如n=8,分解为2、3余3,2+1,3+1,OneSum还余1,所以需要重新从数组末尾再遍历
       //例n=13,分解为2,3,4余4,此操作是三个数皆加一后,将i赋值到flag即数组存储的末尾
       //即 2+1,3+1,4+2 
    }
    for(int i=0;i<=flag;i++){//计算乘积 
      //cout<<a[i]<<endl;执行此操作方便理解 
      OutNum=OutNum*a[i];
    }
    cout<<OutNum<<endl;
    return 0;
  }
}

image.gif


目录
相关文章
|
SQL 存储 大数据
【大数据技术Hadoop+Spark】Hive基础SQL语法DDL、DML、DQL讲解及演示(附SQL语句)
【大数据技术Hadoop+Spark】Hive基础SQL语法DDL、DML、DQL讲解及演示(附SQL语句)
586 0
|
8月前
|
SQL 人工智能 数据处理
《AI赋能SQL Server,数据处理“狂飙”之路》
在数据爆炸的时代,SQL Server作为主流关系型数据库管理系统面临复杂查询与海量数据的挑战。引入人工智能(AI)为优化查询性能提供了全新路径。AI能精准洞察查询瓶颈,优化执行计划;通过预测性维护提前预防性能隐患;智能管理索引以提升查询效率;并基于持续学习实现动态优化。这些优势不仅提高数据处理效率、降低运营成本,还助力企业在数字化竞争中抢占先机,推动SQL Server与AI深度融合,为企业可持续发展注入新动能。
247 4
|
SQL Java HIVE
【解决方案】Hive启动时报错 Logging initialized using configuration in jar:file:/usr/local/apache-hive-1.1.0-bin
【解决方案】Hive启动时报错 Logging initialized using configuration in jar:file:/usr/local/apache-hive-1.1.0-bin
1770 0
【解决方案】Hive启动时报错 Logging initialized using configuration in jar:file:/usr/local/apache-hive-1.1.0-bin
|
Java
Java实例详解
Java实例是通过类创建的对象,其核心在于将抽象的类定义转化为具体的实体。类作为对象的模板定义了属性和行为,而实例则是这些定义的具体实现。通过`new`关键字可以创建实例,并利用点运算符访问其属性和方法。实例拥有自己的生命周期,从创建到使用直至被垃圾回收机制自动清理。此外,实例变量和静态变量的区别在于前者属于单个实例,后者则为所有实例共享。理解Java实例的概念及其管理对编程至关重要。
474 15
|
XML 移动开发 前端开发
使用duxapp开发 React Native App 事半功倍
对于Taro的壳子,或者原生React Native,都会存在 `android` `ios`这两个文件夹,而在duxapp中,这些文件夹的内容是自动生成的,那么对于需要在这些文件夹中修改的配置内容,例如包名、版本号、新架构开关等,都通过配置文件的方式配置了,而不需要需修改具体的文件
|
算法 Java C++
非启发式算法——二分、三分搜索算法
非启发式算法——二分、三分搜索算法
447 0
|
算法 调度
【回溯与分支限界法】最优调度问题
【回溯与分支限界法】最优调度问题
977 0
【回溯与分支限界法】最优调度问题
|
缓存 NoSQL Java
数据库大作业——学生选课系统(基于SpringBoot+Mysql)
一、需求分析 1、项目背景 由于选课时间集中, 在同一时间进入系统抢占有限的资源, 导致系统服务响应速度明显下降, 严重时甚至会造成服务器崩溃。这种问题在目前实行学分制的国内高校中普遍存在。当系统软件不具备高并发性时,就无法顺畅承接超大流量,当请求过多,系统就会直接崩溃。
|
存储 前端开发 Linux
操作系统实验一:时钟中断程序设计
操作系统实验一:时钟中断程序设计
294 0
|
存储 JSON JavaScript
Python处理JSON文件数据各类操作一文详解+实例代码
Python处理JSON文件数据各类操作一文详解+实例代码
1306 0
Python处理JSON文件数据各类操作一文详解+实例代码