银河

SKYIV STUDIO

  博客园 :: 首页 :: 博问 :: 闪存 :: :: :: 订阅 订阅 :: 管理 ::
  268 随笔 :: 2 文章 :: 2616 评论 :: 140万 阅读
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
Timus 1108. Heritage 要求对给定的若干继承人作出一个遗产分配方案。

1108. Heritage

Time Limit: 2.0 second
Memory Limit: 16 MB

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

inputoutput
2
2
3
Problem Author: Pavlin Peev

解答如下:

复制代码
 1 using System;
 2 
 3 namespace Skyiv.Ben.Timus
 4 {
 5   // http://acm.timus.ru/problem.aspx?space=1&num=1108
 6   sealed class T1108
 7   {
 8     static void Main()
 9     {
10       Console.WriteLine(2);
11       int n = int.Parse(Console.ReadLine());
12       BigInteger a = new BigInteger(2);
13       for (int i = 2; i <= n; i++)
14       {
15         BigInteger b = a + 1;
16         Console.WriteLine(b);
17         if (i < n) a *= b;
18       }
19     }
20   }
21 
22   sealed class BigInteger
23   {
24     int[] digits = new int[30000];
25 
26     public BigInteger(int n)
27     {
28       digits[0= n;
29       if (digits[0> 9) Format();
30     }
31 
32     public BigInteger(BigInteger x)
33     {
34       Array.Copy(x.digits, digits, digits.Length);
35     }
36 
37     public static BigInteger operator +(BigInteger x, int y)
38     {
39       BigInteger z = new BigInteger(x);
40       z.digits[0+= y;
41       if (z.digits[0> 9) z.Format();
42       return z;
43     }
44 
45     public static BigInteger operator *(BigInteger x, BigInteger y)
46     {
47       BigInteger z = new BigInteger(0);
48       int xmax = x.digits.Length - 1;
49       int ymax = y.digits.Length - 1;
50       while (xmax >= 0 && x.digits[xmax] == 0) xmax--;
51       while (ymax >= 0 && y.digits[ymax] == 0) ymax--;
52       for (int xi = xmax; xi >= 0; xi--)
53         for (int yi = ymax; yi >= 0; yi--)
54           z.digits[xi + yi] += x.digits[xi] * y.digits[yi];
55       z.Format();
56       return z;
57     }
58 
59     void Format()
60     {
61       for (int quotient = 0, i = 0; i < digits.Length; i++)
62       {
63         int numerator = digits[i] + quotient;
64         quotient = numerator / 10;
65         digits[i] = numerator % 10;
66       }
67     }
68 
69     public override string ToString()
70     {
71       int n = digits.Length - 1;
72       while (n >= 0 && digits[n] == 0) n--;
73       if (n < 0return "0";
74       char[] cs = new char[n + 1];
75       for (int i = n; i >= 0; i--) cs[i] = (char)(digits[n - i] + '0');
76       return new string(cs);
77     }
78   }
79 }
复制代码

这个题目是说,你受命分配一份遗产,共有 N (1 ≤ N ≤ 18) 个继承人,每个继承人将得到整个遗产的若干分之一,且后面的继承人分到遗产的份额不能多于前面的继承人。还有,遗产不能分光,必须捐一部分给教堂。你的任 务是给出一个分配方案使教堂得到的份额最小。其实,这题说穿了也很简单,按以下数列来分配就行了:

a1 = 2, an = (an-1 - 1) * an-1 + 1    (n > 1)

该数列的除第一项外的每一项是其前面所有项的乘积加一,这里的加一就是为了给教堂留一份遗产。令:

Tn = 1 - ( 1/a1 + ... + 1 /an )

很容易证明,Tn = 1 / ( an+1 - 1 ),就是捐给教堂的遗产的份额。如果不加一的话,Tn 就会为零。

这个数列的前几项是:

2, 3, 7, 43, 1807, 3263443, 10650056950807, 113423713055421844361000443,
12864938683278671740537145998360961546653259485195807

关键是这个数列增长太快了,第 18 项居然大于 1026680 。所以需要自己写个简单的 BigInteger 类来计算。

posted on   银河  阅读(900)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· [AI/GPT/综述] AI Agent的设计模式综述
点击右上角即可分享
微信分享提示