USACO算法系列九——kimbits

本文介绍了一种使用分支限界法来解决寻找特定长度且最多包含K个1的二进制串的最小第I个数的问题。通过将二进制串视为二叉树的叶子节点,并采用前序遍历方式,该方法实现了高效的搜索过程。通过剪枝技术,避免了不必要的计算,显著提高了算法效率。经过USACO测试,证明了此方法的有效性和高效率。

    题目:http://www.nocow.cn/index.php/Translate:USACO/kimbits

   求出可以用<=K个1表示的长度为N的二进制串的最小的第I个数。又是01字符串,最先想到方法是遍历1~2^N-1的自然数,如果其中包含1的个数<=K个1表示,则计数加1,直到I为止。但是想想2^31次方可以表示接近2 0000000000的整数,肯定会超时的。

   如果把二进制串当作二叉树的叶子节点,然后采用前序遍历的方式对二叉树进行遍历,往左边走,1的个数不变,往右边走,1的个数加1,满足条件的叶子节点,计数器加1,同时对二叉树进行剪枝。

   (1)当1的个数>K的子树,可以剪枝。

   (2)当K - 1的个数 >= N - 深度,证明剩下的位数可以从全0到全1排满,而此时如果 计数器 + 2 ^ (N - 深度) < I,则计数器直接+ 2 ^ (N - 深度),跳过这个子树。这一步是很关键的。

    (3)如果N <= K,第I小的数为I-1

    (4)如果I <= 2^K -1,则最小数为 I -1

   上面四个剪枝,前两个最为关键,代码如下:

    顺利通过了USACO的测试,速度还不错,测试结果如下:

  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值