SOSdp_子集_超集_卷积

参考:usaxena95’s blog
F [ m a s k ] = ∑ i ∈ m a s k A [ i ] F[mask]=\sum_{i\in mask}A[i] F[mask]=imaskA[i]
模板:
d p [ m a s k ] [ i ] dp[mask][i] dp[mask][i]表示只考虑与 m a s k mask mask在低 i + 1 i+1 i+1位存在不同位数的数字 x x x A [ x ] A[x] A[x]之和。
也就是说: x x x^ m a s k < 2 i + 1 且 x & m a s k = x mask\lt 2^{i+1}且x\&mask=x mask<2i+1x&mask=x.

//iterative version
for(int mask = 0; mask < (1<<N); ++mask){
	dp[mask][-1] = A[mask];	//handle base case separately (leaf states)
	for(int i = 0;i < N; ++i){
		if(mask & (1<<i))
			dp[mask][i] = dp[mask][i-1] + dp[mask^(1<<i)][i-1];
		else
			dp[mask][i] = dp[mask][i-1];
	}
	F[mask] = dp[mask][N-1];
}

//memory optimized, super easy to code.
for(int i = 0; i<(1<<N); ++i)
	F[i] = A[i];
for(int i = 0;i < N; ++i) for(int mask = 0; mask < (1<<N); ++mask){
	if(mask & (1<<i))
		F[mask] += F[mask^(1<<i)];
}

某总结
例题:
CF1208F. Bits And Pieces
链接:link
代码:code

CF165E. Compatible Numbers
链接:link
代码:code

CF383E. Vowels
链接:link
代码:code

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值