poj1405 Heritage(贪心)

来源:互联网 发布:java 迭代器 编辑:程序博客网 时间:2024/06/06 02:31

Heritage
Time Limit: 1000MS Memory Limit: 65536KTotal Submissions: 6548 Accepted: 2409

Description

Your rich uncle died recently, and the heritage needs to be divided among your relatives and the church (your uncle insisted in his will that the church must get something). There are N relatives (N <= 18) that were mentioned in the will. They are sorted in descending order according to their importance (the first one is the most important). Since you are the computer scientist in the family, your relatives asked you to help them. They need help, because there are some blanks in the will left to be filled. Here is how the will looks: 

Relative #1 will get 1 / ... of the whole heritage, 
Relative #2 will get 1 / ... of the whole heritage, 
---------------------- ... 
Relative #n will get 1 / ... of the whole heritage. 

The logical desire of the relatives is to fill the blanks in such way that the uncle's will is preserved (i.e the fractions are non-ascending and the church gets something) and the amount of heritage left for the church is minimized.

Input

The only line of input contains the single integer N (1 <= N <= 18).

Output

Output the numbers that the blanks need to be filled (on separate lines), so that the heritage left for the church is minimized.

Sample Input

2

Sample Output

23


分析:

这道题贪心就好,每个人尽量往大取就好。那么如何保证每次能取到最大呢?

可以注意到,不算church分的,N=i 和N=i-1 时,前面i-1的人分的大小是一样的。比如当N=2时,分别是1/2,1/3;而当N=3时可算出分别是1/2,1/3,1/7。也就是如果用P[i]表示第i个人分多少,那么当N=i时,P[1]~P[i-1]是不需要再算的(前面算出来后存起来就行了)。我们的任务就是算第N个最大可以取多少。

那么如果算第N个呢?就是在剩下的部分里找个比它小的最大的分数。而且可以知道,当N=i时,抛去前面i-1后剩下的部分就是当N=i-1时church分到的那部分。比如还是上面的N=3,前面2个分好后剩下的是1/6,正好是N=2是church的部分。那么我们就算比它小的一个最大的分数,即让上次剩下的数分母加1。1/7就是这么来的。

接下来还有个问题是church分到的部分(剩下的部分)怎么能快速算出来保存起来。自己用几个例子算一下或者用数学推一下就发现,当N=i时,这次剩下的部分的分母=上次剩下的部分的分母*第i个人分到的部分的分母

总结一下就是:设p[i]为每个人分到的部分的分母,设last[i]为当N=i时剩下的部分的分母, 则对于i=2~N有:

p[i]=last[i-1]+1;

last[i]=p[i]*last[i-1];(p[i]=2 , last[1]=2)

最后的问题就是整个过程需要高精度运算。


主代码:

int main()
{
    int N;
    cin>>N;
    last[1]="2";
    p[1]="2";
    string c="1";
    for (int i=2;i<=N;i++)
    {
        p[i]=ADD_INT(last[i-1],c);
        last[i]=MULTIPLY_INT(p[i],last[i-1]);
    }
    for (int i=1;i<=N;i++)
        cout<<p[i]<<endl;
    return 0;
}


原创粉丝点击