P2320 [HNOI2006]鬼谷子的钱袋
程序员文章站
2022-05-08 22:17:15
...
https://www.luogu.com.cn/problem/P2320
求用若干个正整数表示的最小正整数个数以及这些正整数
这些正整数不能重复(除了1)
数据范围:
记得背包的二进制拆分做法吗?用2的正整数次幂是一定能表示出这些数,不过在这道题还不是最优的,这种划分方法严格意义上是有个的,而正解的做法是妥妥的,所以会有误差
考虑分治,设为符合题意的表示的正整数集合
对于一个数,如果它是偶数,那么我们必然可以把它分成两部分,和,也就是说答案是
如果它是奇数,那么我们同样可以把它分成两部分,和
在随便打表找找规律,发现奇数的答案就是的
注意到是正整数,所以把两部分的答案合并起来就是
显然我们只需要每次向集合中加入这个元素,然后递归处理即可
时间复杂度:
#include<cctype>
#include<cstdio>
#define LL long long
using namespace std;int n,j,a[40];
inline LL read()
{
char c;LL d=1,f=0;
while(c=getchar(),!isdigit(c)) if(c=='-') d=-1;f=(f<<3)+(f<<1)+c-48;
while(c=getchar(),isdigit(c)) f=(f<<3)+(f<<1)+c-48;
return d*f;
}
signed main()
{
n=read();
while(n) a[++j]=(n+1)>>1,n>>=1;
printf("%d\n",j);
for(register int i=j;i>0;i--) printf("%d ",a[i]);
}