【BZOJ1192】二进制拆分

题目意思很简单,在这里

题意:
最少将n拆分成多少个数,可以凑出1到n的所有数字。

做题前:
这题是不是假题啊?
我用1 2 3 4 5 …这样凑吧

好像不太对啊。

是dp吗
我想想

这状态怎么表示啊?

昨天刚听过Claris的二进制拆分背包,我试一下吧。

?竟然过了???

分析:
瞎猜一波原理吧。
用二进制拆分一定是可以表示出所有数字的,这个很好理解。
但是为什么二进制拆分是最好的呢?
为什么不是三进制拆分或者更高进制的拆分呢?
举个例子吧

三进制拆分
1 3 9 27…
这个根本凑不出1到n的所有数字,因为他们之间的差距实在是太大了。

更高进制的拆分就更不行了。

试着猜想,应该只有二进制拆分才可以保证左右的数字都可以被组合出来。

遂做完。

#include <bits/stdc++.h>
#define sc(n) scanf("%d",&n)
#define pt(n) printf("%d\n",n)
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define vi vector<int>
#define vl vector<long long>
#define pb push_back
using namespace std;
int main()
{
	int m;
	sc(m);
	cout<<ceil(log2(m))<<endl;
	return 0;
}

代码还没头文件长

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值