ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

P1249 最大乘积(讲题备用)

2022-07-02 14:36:18  阅读:167  来源: 互联网

标签:乘积 高精度 int P1249 讲题 -- 余数 string


P1249 最大乘积 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

 

 

这道题涉及到简单的贪心和数论以及高精度乘法
这道题我们要解决两个问题:1.求乘积最大时的每一项;2.求乘积(高精度)
首先这道题求:整数n分成若干个互不相同的自然数之和,使这些自然数的乘积最大
根据贪心的思想,一般是能分出的份数越多,乘积越大
所以我们可以从2开始累加,直到新的加数大于余数
拿15为例:
15:s=2+3+4+5此时余数是1,未来新的加数为6

对于余数,我们不难想有这样的结论:从大数开始向前,依次分配1,这样的乘积最大
那么把5+1就是最后的答案

那假设我们有m项(第m项值为m+1),从m+1项(第m+1项值为m+2)开始新的加数大于余数
那么此时最大的余数是m+1,也就是说此时加完一轮后还剩1,那把这个1给最大项即可

此外还要注意特判:1-4时,其本身就是最大值

高精度乘法:
为了方便使用高精度,我们在存储每一项时,用整形和字符串型存两次(整形是为了方便输出)
高精度乘有两个写法:
一个是借助高精度加法,把乘法转换为多次加法
一个是模拟竖式乘法
这里选用第二种,因为更加简短,大家也都有板子,这里不做过度解释

  1 #include<iostream>
  2 #include<algorithm>
  3 using namespace std;
  4 const int L=500;
  5 //高精度乘法
  6 string mul(string a,string b)
  7 {
  8     string s;
  9     int na[L],nb[L],nc[L],La=a.size(),Lb=b.size();
 10     fill(na,na+L,0);
 11     fill(nb,nb+L,0);
 12     fill(nc,nc+L,0);
 13     for(int i=La-1;i>=0;i--) na[La-i]=a[i]-'0';
 14     for(int i=Lb-1;i>=0;i--) nb[Lb-i]=b[i]-'0';
 15     for(int i=1;i<=La;i++)
 16     {
 17         for(int j=1;j<=Lb;j++)
 18         {
 19             nc[i+j-1]+=na[i]*nb[j];
 20         }
 21     }
 22     for(int i=1;i<=La+Lb;i++)
 23     {
 24         nc[i+1]+=nc[i]/10;
 25         nc[i]%=10;
 26     }
 27     if(nc[La+Lb]) s+=nc[La+Lb]+'0';
 28     for(int i=La+Lb-1;i>=1;i--)
 29     {
 30         s+=nc[i]+'0';
 31     }
 32     return s;
 33  }
 34  //把整形转换为字符串
 35 string f(int a)
 36 {
 37     char ch[10],t;
 38     int i=0;
 39     int j;
 40     while(a)
 41     {
 42         ch[i]=a%10+'0';
 43         a/=10;
 44         i++;
 45     }
 46     ch[i]='\0';
 47     //字符数组的倒序 
 48     for(i=i-1,j=0;j<=i/2;j++,i--)
 49     {
 50         t=ch[i];
 51         ch[i]=ch[j];
 52         ch[j]=t;
 53     }
 54     return ch;
 55 }
 56 
 57 int n,a[1005];
 58 string s[1005];
 59 int c=1;
 60  int main()
 61  {
 62      string m="1";
 63      //输入 
 64      cin>>n;
 65      //特判 
 66      //如果n小于5,自己本身就是最优解
 67      if(n<=4)
 68      {
 69          cout<<n<<endl<<n;
 70          return 0;
 71       }
 72       //拆项 
 73      for(int i=2;i<=n;i++)
 74      {
 75          if(n>=i)
 76          {
 77              n-=i;
 78              a[c++]=i;
 79              s[c-1]=f(i);
 80         }
 81         else
 82         break;
 83      }
 84      //如果有余数,从最高位开始加一
 85      for(int i=c-1;i>=1;i--)
 86      {
 87          if(n>0)
 88          {
 89          a[i]++;
 90          s[i]=f(a[i]);
 91          n--;
 92         }
 93      }
 94      //分过一轮后,如果还多,就让最后一个数加一,余数<=n
 95      if(n>0)
 96      {
 97          a[c-1]++;
 98          s[c-1]=f(a[c-1]);
 99      }
100      //高精度乘 
101      for(int i=1;i<c;i++)
102      {
103          //输出分出的整数
104          cout<<a[i]<<" ";
105          m=mul(s[i],m);
106      }
107      cout<<endl<<m;
108      return 0;
109  }

 

标签:乘积,高精度,int,P1249,讲题,--,余数,string
来源: https://www.cnblogs.com/inawaken/p/16437495.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有