【CF-1348 D. Phoenix and Science】构造

D. Phoenix and Science

题意

开始有一个质量为1的细菌,每天你可以控制任意数量的细菌分裂,一个质量为\(m\)的细菌分裂为两个质量为\(m/2\)的细菌,
每天晚上,所有细菌的质量会增加1,问最少需要多少天可以使得细菌的质量和为n,

思路

每天质量增加的大小为 细菌的个数,现在要构造出一个尽可能短,\(a[0]=1\),满足\(a[i-1]\leq a[i]\leq a[i-1]*2\)并且和为n的数组,来表示
每天细菌的数量;

因为要尽可能的短,就让当前天数的细菌为前一天的二倍,这样最后可能会出现递减。

比如:18 : 1 2 4 8 3

这时,把最后两个元素取平均值就可以了,上面变为1 2 4 5 6。

这样一定是最小值。

代码

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
const int inf=0x3f3f3f3f;
typedef long long ll;

int arr[N];
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n,cnt;
        scanf("%d",&n);
        n--;
        arr[cnt=0]=1;
        while(n)
        {
            ++cnt;
            arr[cnt]=min(n,arr[cnt-1]*2);
            n-=arr[cnt];
        }
        printf("%d\n",cnt);
        if(arr[cnt-1]>arr[cnt])
        {
            int sum=arr[cnt-1]+arr[cnt];
            arr[cnt-1]=sum/2;
            arr[cnt]=sum-arr[cnt-1];
        }
        for(int i=1;i<=cnt;i++)
            printf("%d ",arr[i]-arr[i-1]);
        printf("\n");
    }
    return 0;
}
posted @ 2020-05-26 22:23  Valk3  阅读(120)  评论(0编辑  收藏  举报