二进制总结(算法竞赛进阶指南)

常用操作

最右一位为第0位,从右到左依次为 0, 1, 2, 3…… 
取出n的第k位                              (n >> k) & 1
取出n的第0~k-1位                       n & ((1 << k) - 1)
n的第k位取反                              n ^ (1 << k) 
n的第k位赋值为1                         n | (1 << k)
n的第k位赋值为0                         n & (~(1 << k))

 

二进制状态压缩例题: 最短Hamliton路径

给定一张 n(n≤20) 个点的带权无向图,点从 0~n-1 标号,求起点 0 到终点 n-1 的最短Hamilton路径。 Hamilton路径的定义是从 0 到 n-1 不重不漏地经过每个点恰好一次。

核心代码

int f[1 << 20][20];
memset(f, 0x3f, sizeof(f));
f[1][0] = 0;
REP(i, 1, 1 << n)
	REP(j, 0, n) if((i >> j) & 1)
		REP(k, 0, n) if((i >> k) & 1)
			f[i][j] = min(f[i][j], f[i^(1<<j)][k] + w[k][j]);
printf("%d\n", f[(1<<n)-1][n-1]);

 

lowbit

表示非负整数n在二进制下最低位1以及它后面的0构成的数值

比如n = 1010101000100

lowbit(n) = 100

lowbit(n) = n & (-n)

 
快速求二进制中1的个数

int num(int x) { return !x ? 0 : 1 + num(x & (x - 1)); }

x & (x - 1) 可以把二进制中最后一位1去掉
比如10100变成10000

这里减去lowbit(x)也可以

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值