Luogu P1249 最大乘积

link

最大乘积

题目描述

一个正整数一般可以分为几个互不相同的自然数的和,如 3=1+24=1+351+4=2+36=1+52+4

现在你的任务是将指定的正整数 n 分解成若干个互不相同的自然数的和,且使这些自然数的乘积最大。

输入格式

只一个正整数 n,(3n10000)。

输出格式

第一行是分解方案,相邻的数之间用一个空格分开,并且按由小到大的顺序。

第二行是最大的乘积。

样例 #1

样例输入 #1

10

样例输出 #1

2 3 5
30

思路

本题要先用数论和贪心找到最优解的组成方法,再用高精度乘法求积。

先来列举观察:
3=3
4=4
5=2+3
6=3+3
8=3+5
9=2+3+4
10=2+3+5

观察发现,几乎每个正整数都可以使用近乎相邻的数字之和表示,而这恰好是最大乘积的方案。于是就顺着发现大胆猜测:自然数的分解乘积最大方案是一组相邻的数字序列。

接着便萌生了贪心的猜想:循环列举数字2,3,4,…,n1,同时求总和sum,当sum大于n时停止循环,将序列中sum-n的元素删去,使得sum=n,这正好是最终方案。

最后,再套用高精度乘法模版即可。

#include<bits/stdc++.h>
using namespace std;
int a[10001];
int b[10001],len=1;
void sv(int x)
{
for(int i=1;i<=len;i++)
{
b[i]*=x;
}
for(int i=1;i<=len;i++)
{
b[i+1]+=b[i]/10;
b[i]%=10;
}
while(b[len+1]!=0)
{
len++;
b[len+1]+=b[len]/10;
b[len]%=10;
}
}
int main()
{
ios::sync_with_stdio(false);
int n;
cin>>n;
if(n<=4)
{
cout<<n<<endl<<n<<endl;
return 0;
}
int sum=0,k=0;
for(int i=2;sum<n;sum+=i,i++)
{
k++;
a[k]=i;
}
if(sum>n+1)
{
a[sum-n-1]=0;
}
else if(sum==n+1)
{
a[k]+=1,a[1]=0;
}
b[0]=b[1]=1;
for(int i=1;i<=k;i++)
{
if(a[i])
{
cout<<a[i]<<" ";
sv(a[i]);
}
}
cout<<endl;
for(int i=len;i>=1;i--)
{
cout<<b[i];
}
cout<<endl;
return 0;
}
posted @   j1hx  阅读(34)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
点击右上角即可分享
微信分享提示