算法实现题 4-15 最优分解问题
问题描述:
设 n 是一个正整数。现在要求将 n 分解为若干个互不相同的自然数的和,且使这些自然数的乘积最大。
算法设计:
对于给定的正整数 n,编程计算最优分解方案。
数据输入:第 1 行是正整数 n。
结果输出:将计算的最大乘积输出到屏幕。
input:10
output:30
10=2+3+5;
30=2*3*5;
来自以下博文:
问题分析: 整数的一个性质:若 a + b =N(常数),则| a - b |越小, a * b 越大
贪心策略:将n分成从2开始的连续自然数的和,如果最后剩下一个数,将此数在后项优先的方式下均匀地分给前面各项。
该贪心策略首先保证了正整数所分解出的因子之差的绝对值最小,即|a - b|最小;同时又可以将其分解成尽可能多的因子,且因子的值较大,确保最终所分解的自然数的乘积值。
以下引用内容有点问题,慎看!
当n小于4的时候,就会出现矛盾,,,,,,
比如n=4,最小从2开始,剩余2,不够3,这个时候就要均分给前面的数字每人一个1,可是前面只有1个数字,全加给那一个数吧,又相当于没有分解,要是不从2开始,从1开始分解,对于其他大数又不合理,,,要单独考虑,这个程序可能把那个剩下的1分给了越界的数组下标,还要保证题目上的互不相同的要求,只能理解成分为1+3,乘积最大是3。。。
#include<bits/stdc++.h>
using namespace std;
int main() {
int n;
cin>>n;
int x=n;
int i=2,j=0,a[99999];
while(x>=i) {
a[j++]=i;
x=x-i;
i++;
}
int p=j;//记录分解的因数的个数
j--;//最后一个a数组所在位置的下标
while(x--) {
a[j]++;
j=(j-1+p)%p;//考虑到剩余的数大于分解的因数的个数的情况
}
int sum=1;
for(int s=0; s<p; s++) {
sum=sum*a[s];
}
cout<<sum<<endl;
return 0;
}