1 条题解
-
0
为了最小化教堂的遗产,我们需要尽可能让亲属分配的总和接近1。这可以通过贪心地选择尽可能小的分母来实现,同时确保分母是严格递增的(因为 必须非递增)。
初始化: • 第一个分母 (因为 已经等于全部遗产,教堂得不到任何东西)。
• 当前总和 。
选择后续分母: • 对于第 个分母 ,选择最小的整数 满足:(保证 ) ,其中 是前 个亲属分配的总和。
• 因此, 是满足 且 是 的最小整数。
更新总和: • 每次选择 后,更新总和 。
终止条件: • 当所有 个分母都选择完毕后,算法终止。
代码实现
#include<stdio.h> #include<stdlib.h> #define inf 1000000000 #define maxn 100000 int len1, len2, len3, len[18]; long long a[maxn], b[maxn], ans[maxn], res[18][maxn]; void setAns() { for (int i = 0; i < len3; i++) { ans[i] = 0; } } void copy() { for (int i = 0; i < len3; i++) { a[i] = ans[i]; } len1 = len3; } void multiply() { int i, j; setAns(); for (i = 0; i < len2; i++) { for (j = 0; j < len1; j++) { ans[i+j] += a[j] * b[i]; ans[i+j+1] += ans[i+j] / inf; if (ans[i+j+1] && len3 <= i + j + 1) { len3 = i + j + 2; } else if (len3 <= i + j) { len3 = i + j + 1; } ans[i+j] %= inf; } } } void plus() { int r; for (len2 = 0, r = 1; len2 < len1; len2++) { r += a[len2]; if (r >= inf) { b[len2] = r - inf; r = 1; } else { b[len2] = r; r = 0; } } if (r) { b[len2++] = r; } } int main() { int i, j, n; scanf("%d", &n); a[0] = 2; len1 = 1; printf("2\n"); for (i = 2; i <= n; i++) { plus(); printf("%lld", b[len2-1]); for (j = len2 - 2; j >= 0; j--) { printf("%.9lld", b[j]); }printf("\n"); if (i < n) { multiply(); copy(); } } return 0; }
- 1
信息
- ID
- 406
- 时间
- 2000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 2
- 已通过
- 1
- 上传者