poj 1032 Parliament 把自然数N分解成若干个互不相同的正整数,使乘积最大;

若 把自然数N分解成若干个正整数(可以相同),使乘积最大,方法是: a[n]=3*a[n-3]; if(n<=4) return n;

 

 

 

 

Parliament
Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 12324 Accepted: 5134

Description

New convocation of The Fool Land's Parliament consists of N delegates. According to the present regulation delegates should be divided into disjoint groups of different sizes and every day each group has to send one delegate to the conciliatory committee. The composition of the conciliatory committee should be different each day. The Parliament works only while this can be accomplished.
You are to write a program that will determine how many delegates should contain each group in order for Parliament to work as long as possible.

Input

The input file contains a single integer N (5<=N<=1000 ).

Output

Write to the output file the sizes of groups that allow the Parliament to work for the maximal possible time. These sizes should be printed on a single line in ascending order and should be separated by spaces.

Sample Input

7

Sample Output

3 4
#include<iostream>
#include<cstdio>
using namespace std;
//把自然数N分解成若干个互不相同的正整数,使乘积最大;
/**
题意挺晦涩的,就是说要维持这个会议召开需要满足几个条件,而要会议召开最久需要这个条件尽可能久的维持
接着就需要了将整数N分解任意个不同的整数,使这些整数的乘积最大
将N分解为N=a1+a2+a3+..+ak
可以归纳出这么一些规律
1.a1>1  如果a1=1,那么将a1加到ak上,必然使得到的这个乘积大于原来的乘积
2.2>=a[i+1]-a[i]>=1,因为如果出现>2,可以将a[i+1],a[i]改为a[i+1]-1,a[i]+1,使得到的乘积更大
3.最多只有一个i,使得a[i+1]-a[i]=2
  反证法,假设i<j,并且a[i+1]-a[i]=2,a[j+1]-a[j]=2,那么将a[i],a[j+1]替换成a[i]+1,a[j+1]-1
  将使得乘积更大
4.a1<=3 如果a1>=4,那么将a1,a2替换成2,a1-1,a2-1将使得乘积更大
5.如果a1=3,并且存在一个i使得a[i+1]-a[i]=2,那么i一定为t-1
做法就是求出以2起始的最大连续自然数序列之和sum,使得sum的值不超过输入数n,
然后分情况讨论:
设此最大序列为2、3、……、w,则:
1。若剩余值(n-sum)等于w,则最后输出序列为:3、4、……、w、w+2,即将原最大序列每项加1,再将最后剩余的一个1加到最后一项上。
2。若剩余值(n-sum)小于w,则从序列的最大项i开始,从大到小依次将每项加1,直到剩余值用完。
*/

int a[1000];
int n;
int main()
{
    while(scanf("%d",&n)==1)
    {
        int sum=0,l=0,left;
        for(int i=2;i<=n;i++)
        {
            a[l++]=i;
            sum+=i;
            if(sum>n)
            {
                sum-=i,l--,left=n-sum;
                break;
            }
        }
        for(int i=l-1;left;left--)
        {
            a[i]++;
            i--;
            if(i<0) i=l-1;
        }
        for(int i=0;i<l-1;i++) printf("%d ",a[i]);printf("%d/n",a[l-1]);
    }
    return 0;
}
  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值