Survive in the White Terror

Problem B: Survive in the White Terror

Time Limit: 1 Sec  Memory Limit: 128 MB
Submit: 127  Solved: 31
[Submit][Status][Web Board]

Description

       In 1927~1949, the whole of China were enveloped in the white terror. Many revolutionary people were killed by the kuomintang reactionaries. N people wanted to fight back. They divide into several groups, and the size of each group are different from each other. Everyday, each group sent one people to a new work-group. The work-group has been guarded by reactionaries. So the composition of the work-group should be different each day. If not, the reactionaries will notice that the group has been shown before, and all of them will be arrested and killed.

       Duncan is the leader of the people who fight against KMT. He wonders that how many people should contain each group in order to make the work-group survive as long as possible. Can you help him?

Input

Each line of the input contains a single integer N (3<=N<=1000), terminated by EOF.

Output

For each input, write to the output file the sizes of groups that allow the work-group to survive maximal possible time. These sizes should be printed on a single line in ascending order and should be separated by a space.

Sample Input

3
7
10

Sample Output

1 2
3 4
2 3 5

題意:
現在有N個士兵,將它們進行分組,每個組的人數互不相同。每一天每個組將派一名士兵去一個新的組,每個組的組成每天都必須不一樣,不然將會被國民黨全部殺害,
現在,如果要經可能生存較長的時間,改怎樣對這批士兵進行分組。
題意轉化:
比如一個組有M個人,另一個組有N個人,每次派一個人去另一個組,這樣便有M*N中組合方法。要想生存的更長,那就必須滿足這種組合方式最多。
該題就能轉化爲:將N拆分成互不相同的數,使得它們的乘積最大。

解題思路:
  把自然數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,直到剩餘值用完。

代碼實現:
#include <iostream>
using namespace std;
int num[1000];
int main()
{
    int N,sum,temp,l;
    while(cin>>N)
    {
        if(N==3)
        cout<<N/2<<" "<<N-N/2<<endl;
        else if(N==4)
        cout<<N/3<<" "<<N-N/3<<endl;
        else
        {
            
        sum=l=0;
        for(int i=2;i<=N;i++)
        {
            num[l++]=i;
            sum+=i;
            if(sum>N)
            {
                sum-=i;
                l--;
                temp=N-sum;
                break;
            }
        }
        for(int j=l-1;temp;temp--)
        {
            num[j]++;
            j--;
            if(j<0)j=l-1;
        }
        for(int i=0;i<l-1;i++)
            cout<<num[i]<<" ";
        cout<<num[l-1]<<endl;
        }
    }
}





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章