1 条题解

  • 0
    @ 2025-5-1 16:44:51

    为了最小化教堂的遗产,我们需要尽可能让亲属分配的总和接近1。这可以通过贪心地选择尽可能小的分母来实现,同时确保分母是严格递增的(因为 1di\frac{1}{d_i} 必须非递增)。

    初始化: • 第一个分母 d1=2d_1 = 2(因为 11=1\frac{1}{1} = 1 已经等于全部遗产,教堂得不到任何东西)。

    • 当前总和 S=12S = \frac{1}{2}

    选择后续分母: • 对于第 ii 个分母 did_i,选择最小的整数 did_i 满足:di>di1d_i > d_{i-1}(保证 1di<1di1\frac{1}{d_i} < \frac{1}{d_{i-1}}1di<1S\frac{1}{d_i} < 1 - S ,其中 SS 是前 i1i-1 个亲属分配的总和。

    • 因此,did_i 是满足 di>di1d_i > d_{i-1}did_i11S+1\left\lfloor \frac{1}{1 - S} \right\rfloor + 1 的最小整数。

    更新总和: • 每次选择 did_i 后,更新总和 S=S+1diS = S + \frac{1}{d_i}

    终止条件: • 当所有 nn 个分母都选择完毕后,算法终止。

    代码实现

    #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
    上传者