zoukankan      html  css  js  c++  java
  • 正整数分解使得乘积最大问题(转载)

    转载:https://blog.csdn.net/xiaoquantouer/article/details/70142739

    一、问题描述

    设n是一个正整数。现在要求将n分解为若干个自然数之和,使得自然数的成绩最大。输出这个最大的乘积。

    要求:

    (1)要求这些自然数互不相同

    (2)要求这些自然数可以是相同的

    二、问题分析:

    这类题一开始需要我们手写几个数来看看规律。先做第一问,要求自然数互不相同。从5开始写起,5=2+3,6=2+4,7=3+4,8=3+5,9=2+3+4,10=2+3+5,11=2+4+5

    发现规律如下:

    (1)尽量使得元素是连续的。

    (2)如果有多出来的,从后往前均匀分配到各个元素。考虑到一种特殊情况,当多出来的数比前面已有元素的个数大1时(比如8的情况),先给已有元素的最大元素加1,然后再均匀分配到每个元素。

    下面举个栗子,看看携程实习生招聘笔试的这道题:

    题目描述:乘积最大

    有一个整数n,将n分解成若干个不同自然数之和,问如何分解能使这些数的乘积最大,输出这个乘积m。

    输入:

    一个整数,不超过50

    输出

    一个整数

    样例输入

    15

    样例输出

    144

     1 #include<iostream>
     2 #include<vector>
     3 using namespacestd;
     4  
     5 int main(){
     6     int num;
     7     while(cin>>num){
     8         int flag[100] = {0};
     9         int k=2;
    10         int i=0;
    11         while(num >= k){
    12             //从2开始分解,依次分解为2,3,4,5...连续的元素
    13             flag[i++] = k;
    14             num -= k;
    15             k++;
    16         }
    17         if(num > 0){
    18             //说明有剩余的
    19             if(num == flag[i-1]){
    20                 //说明这时候剩余的数正好比已有的元素个数多1,所以要先给最后一个元素加1
    21                 flag[i-1]++;
    22                 num--;
    23             }
    24             for(int j=i-1;j>=0 &&num>0;j--){
    25                 flag[j] ++;
    26                 num--;
    27             }
    28  
    29         }
    30         int result = 1;
    31         for(int j = 0;j<i;j++){
    32             result *= flag[j];
    33         }
    34         cout<<result<<endl;
    35     }//while
    36     return 0;
    37 }

    对于第二问,对于元素可以是相同的

    仍然是通过手写几个数查看一下规律:4=2+2,5=2+3,6=3+3,7=3+2+2,8=3+3+2,9=3+3+3。

    发现规律如下:

    (1)元素不会超过4,因为4=2+2,又可以转化为2的问题,而5=2+3,5<2*3,所以5总能分解成2和3。

    (2)尽可能多分解出3,然后分解出2,不要分出1。

    考虑任意一个数,除以3之后的结果有以下3种:

    (1)能被3除断,那么就分解为3+3+...+3的情况即可。例如9=3+3+3。

    (2)被3除余1,分解为3+3+...+3+2+2或者3+3+...+3+4的情况,例如10=3+3+2+2

    (3)被3除余2,分解为3+3+...+3+2的情况,例如11=3+3+3+2。

     1 #include<iostream>
     2 #include<math.h>
     3 usingnamespace std;
     4  
     5 int main(){
     6     int num;
     7     while(cin>>num){
     8         if(num % 3 == 0){   //考虑被3整除的情况
     9             cout<<pow(3,num/3)<<endl;
    10             continue;
    11         }
    12         int flag[100] = {0};
    13         int i=0;
    14         while(num != 2 && num != 4){
    15             //如果不能被3整除,那么除3必余1或者2,而余1和4是同样的情况,这里取4是因为这种情况下最后是两个2,
    16             //取4就可以直接把4分解为2+2
    17             flag[i++]=3;
    18             num-=3;
    19         }
    20         while(num){  //余2和1的情况,余2就是1个2,余1就是2个2,所以前面才会判断是否等于4,这样就可以化为2个2
    21             flag[i++] = 2;
    22             num-=2;
    23         }
    24         int result = 1;
    25         for(int j=0;j<i;j++){
    26             result *= flag[j];
    27         }
    28         cout<<result<<endl;
    29     }//while
    30     return 0;
    31 }
  • 相关阅读:
    2014编程之美资格赛 第二题 大神和三个小伙伴
    操作系统PV操作——进程同步问题(C#实现)
    [转_管理]成功者必备的15种能力
    [技术相关]List、Dictionary转Dictionary的性能分析
    [项目管理]怎样评定软件开发成果的质量
    Visual Studio 2013 RTM 中文语言包官方下载地址发布
    IIS7报错:如果要使用托管的处理程序,请安装 ASP.NET
    HTTP请求方式中get和post的区别
    asp.net之动态页面和静态页面的区别
    HTML语言语法大全
  • 原文地址:https://www.cnblogs.com/henuliulei/p/9997909.html
Copyright © 2011-2022 走看看