您的位置:首页 > 其它

cug1124 分组积最大

2015-07-15 16:14 344 查看
题目大意:讲一个数n分解为不小于两个数的不相等的自然数的和,使得积最大。

思路:一个数n=a1+a2+a3 + ……+ak;要是积最大,则必然有如下规律:

1.若m可分解为m1(m1>=2)+m2(m2>=2) 则必然有m1*m2>m.若m1或m2等于1,则m1*m2<m,不分即可最大。故ai(1<= i <= k) > 1;

2.因为每个数不能相同,设dis = a[i+1]-a[i],有1<=dis<=2;若dis>2,则有(a[i+1]-1)*(a[i]+1) > (a[i+1]*a[i]);

3.最多只有一个dis==2;若出现两个则必然可以出现更有分解序列,反证法证明,此处不做证明。

4.a1<=3.若a1>3,必然可以将a1,a2分解为三个数,使得乘积大于a1*a2.

解决方法:

从自然数2开始求sum,sum<=n,Arr[]保存分解序列。

设dis = n - sum;则必有dis<=k+1;将dis从Arr[k]开始,从打到小依次为每个序列至加1,直至dis=0.若dis=k+1,将最后一个1加到Arr[k],如此,可保证得到最大积。

注:因为最少分两组,n从3开始。所以这种方法不能求3 ,4.故需要特判一下。

#include <iostream>
#include <string>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdio>

using namespace std;
int Arr[500];

int main()
{
int n;
while(scanf("%d" , &n) != EOF)
{
if(n == 3)
{
cout << "1 " << "2" << endl;
continue;
}
if(n == 4)
{
cout << "1 " << "3" << endl;
continue;
}
int sum = 0;
int k = 0;
for(int i = 2 ; i <= n ; i ++ )
{
sum += i;
if(sum > n)
{
sum -= i;
break;
}
Arr[k++] = i;
}
int dis = n - sum;
for(int i = k - 1 ; dis > 0 ;  dis --)
{
Arr[i] ++ ;
i -- ;
if(i < 0) i = k - 1;   //如果不能分完则将最后一个加1
}
for(int i = 0 ; i < k ; i ++ )
{
if(Arr[i] != 0 )
{
cout << Arr[i];
if(i < k - 1) cout << " ";
}
}
cout << endl;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: