对 sosdp 的一些理解

sosdp 可以做的题目:对子集/超集的 dp,这里对子集相关的部分做一下分析

参考资料
f[mask][i] 表示从低到高考虑到 mask 的第 i 位(从 0 开始算),而且这 i+1 位都是 mask 的子集并且第 i+1 位及以上都和 mask 完全相同时的和
那么只需要对 mask 的第 i 位进行分析来转移

  • 该位为 0,那么显然这一位只能取 0,也就是说 f[mask][i]f[mask][i1]
  • 该位为 1,那么这一位可以取 0/1 ,f[mask][i]{f[mask][i1]f[mask2i][i1]

代码如:

for(int mask = 0; mask < (1<<N); ++mask){
	dp[mask][-1] = A[mask];	
	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];
}

滚存一下就得到了常见的写法:

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)];
}

时间复杂度 O(n2n)

posted @   SkyRainWind  阅读(46)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 记一次.NET内存居高不下排查解决与启示
点击右上角即可分享
微信分享提示