将n分解为若干互不相同的自然数的和,并且使这些自然数的乘积最大,最大乘积是多少?
方法一:(这个好像错了,别看这个,还在想怎么改进)
动态规划
#include <bits/stdc++.h>
using namespace std;
int main(){
int n;
cin>>n;
int a[100];
//记录每个数的最大乘积是由该数的哪两个数分解而来的
int flag[100][2];
//初始最大乘积为该数本身(不分解)
for(int i=1;i<=n;i++){
a[i]=i;
flag[i][0]=i;
flag[i][1]=-1;
}
//从3开始分别求最大值
for(int i=3;i<=n;i++){
for(int k1=1;k1<=(i+1)/2;k1++){
int k2 = i-k1;
//i=k1+k2,用k1和k2的最大值a[k1]*a[k2],但是要注意a[k1]和a[k2]的组成不能相同
if(k1!=k2&&flag[k1][0]!=k2&&flag[k1][1]!=k2&&flag[k2][0]!=k1&&flag[k2][1]!=k1&&a[k1]*a[k2]>a[i]){
a[i]=a[k1]*a[k2];
flag[i][0]=k1;
flag[i][1]=k2;
}
//i=k1+k2,用k1和k2本身
if(k1!=k2&&k1*k2>a[i]){
a[i]=k1*k2;
flag[i][0]=k1;
flag[i][1]=k2;
}
}
cout<<a[i]<<" ";
}
return 0;
}
方法二(搬运):
若a+b等于一个常数,则|a-b|越小,ab就越大。
要使得加数互不相同,又尽可能集中,那加数只能是连续的自然数了。
将n分成从2开始的连续的自然数的和。如果最后剩下一个数,
将此剩余数从后项开始的方式下均匀地分给前面各项。
如:10
首先分解为:2+3+4 剩余 1
从后开始,所以 1 加到 4 上
变成 2+3+5,此时乘积最大
原文链接:https://blog.csdn.net/LDUtyk/article/details/53898892
#include <stdio.h>
int main()
{
int n;
int a[100];
scanf("%d",&n);
int x=2;
int index=0;
a[index++]=x;
n-=x;
while(n>a[index-1])
{
a[index]=a[index-1]+1;
n-=a[index];
index++;
}
int num=index-1;
while(n)
{
a[num]++;
num=(num-1+index)%(index);
n--;
}
int result=1;
for(int i=0;i<index;i++)
{
result*=a[i];
}
printf("%d\n",result);
return 0;
}