【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;
}