子集和dp

子集和dp

用处

  1. 统计n维偏序,但是每一维的大小只能是2。
  2. 计算子集权值之和。

实际上以上两种问题是等价的。
例如目前有一个集合:101(其中1表示有某个物品,0表示没有)。
那该集合包涵的子集有4个:101,100,001,000。现在要把这4个集合的权值加起来。

按照第二种理解(用处),我们可以一位一位地来dp计算贡献。
fi,j 表示正在计算数字j的贡献,处理到了第i位的答案(也可以理解为前i位与j可能不同,但后面的位都与j相同)。

转移方程:
若j的第i位为0,则这一位只能为0 :fi,j=fi1,j
若j的第i位为1,则这一位能为1或0:fi,j=fi1,j+fi1,k
其中,k的第i位是0,其余位与j相同,即 k=j2i

外层循环枚举i,可把i那一位滚掉。实际写的时候是在计算fi1,k时来更新fi,j。反正 fi1,j也不会去更新其他数,所以内层枚举顺序不重要。

代码短小精悍:

for(int j = 1; j < (1<<K); ++j) f[j] = val[j];//init
for(int i = 0; i < K; ++i) 
  for(int j = 0; j < (1<<K); ++j)
    if(!(j >> i & 1)) f[j | (1 << i)] += f[j];

复杂度是非常标准的O(MlogM), 其中M为值域。

例题:为了可以带修改,使用根号重构。

注意:每次子集和dp的复杂度都是与值域相关,与实际数的个数无关(考虑优化)。

posted @   花子の水晶植轮daisuki  阅读(10)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
https://blog-static.cnblogs.com/files/zouwangblog/mouse-click.js
点击右上角即可分享
微信分享提示