Sum over Subsets(SOS) DP

一、引入

给出一个长度为\(2^n\)的数组\(A\),对于每一个\(mask< 2^n\)要求计算出\(f[mask]=\sum_{sub\in mask}A[sub]\)

(其中\(sub\in mask\)表示\(sub\&mask=sub\))

二、解法

1.暴力

for(int mask = 0; mask < (1<<n); mask++)
for(int sub = 0; sub <= mask; sub++)
if((sub & mask) == sub)
f[mask] += A[sub];

根据定义直接做,枚举所有小于\(mask\)的集合,判断\(sub\)是否是\(mask\)的子集

复杂度\(O(4^n)\)

2.子集枚举

for(int mask = 0; mask < (1<<n); mask++){
for(int sub = mask; ; sub = mask&(sub-1)){
f[mask] += A[sub];
if(!sub) break;
}
}

子集枚举优化之后

总复杂度是\(\sum_{m=0}^{n}C(n,m)\cdot 2^m = \sum_{m=0}^{n}C(n,m)\cdot 2^m\cdot 1^{n-m}=(1+2)^n\)

复杂度\(O(3^n)\)

3.SOSDP

考虑在计算当前的状态的\(f[mask]\)的时候,能否利用之前计算的结果来优化复杂度,并且不会重复计算

那就要定义新的状态:\(f[mask][bit]\)表示对于集合\(mask\),在子集\(sub\)和\(mask\)只有最后\(bit\)位存在不同的情况下的答案

可以发现\(f[mask][bit]= \begin{cases} A[mask] & bit=-1 \\ f[mask][bit-1] & mask\&(1<<bit)=0 \\ f[mask][bit-1]+f[mask \bigoplus (1<<bit)][bit-1] & mask\&(1<<bit)!=0 \end{cases}\)

当前位是\(1\)的情况下有两个分支,这个位置是\(1\)或者\(0\),并且从只改变之后的位的状态转移过来,能保证不重复

当前位是\(0\)的情况下这个位不能改变,所以只能选这位是\(0\)的之后的状态转换过来

空间压缩一下,代码如下

for(int mask = 0; mask < (1<<n); mask++) f[mask] = A[mask];
for(int bit = 0; bit < n; bit++)
for(int mask = 0; mask < (1<<n); mask++)
if(mask&(1<<bit)) f[mask] += f[mask^(1<<bit)];

复杂度\(O(n2^n)\)

考虑一下如何计算\(f[sub]=\sum_{sub \in mask} A[mask]\)

可以发现把所有集合取反,\(f[\overline{sub}] = \sum_{\overline{mask}\in \overline{sub}}A[\overline{mask}]\)

就相当于把\(0\)变成\(1\)来处理,代码基本相同

for(int mask = 0; mask < (1<<n); mask++) f[mask] = A[mask];
for(int bit = 0; bit < n; bit++)
for(int mask = 0; mask < (1<<n); mask++)
if(!(mask&(1<<bit))) f[mask] += f[mask^(1<<bit)]; // 只有这里的if改了

三、例题

  1. Codeforces165E 代码
  2. Codeforces383E 代码
  3. Codeforces449D 代码
  4. Codeforces1208F 代码
  5. Hdu5977 代码

参考CF博客

SOS DP学习笔记的更多相关文章

  1. 数位DP学习笔记

    数位DP学习笔记 什么是数位DP? 数位DP比较经典的题目是在数字Li和Ri之间求有多少个满足X性质的数,显然对于所有的题目都可以这样得到一些暴力的分数 我们称之为朴素算法: for(int i=l_ ...

  2. DP学习笔记

    DP学习笔记 可是记下来有什么用呢?我又不会 笨蛋你以后就会了 完全背包问题 先理解初始的DP方程: void solve() { for(int i=0;i<;i++) for(int j=0 ...

  3. 树形DP 学习笔记

    树形DP学习笔记 ps: 本文内容与蓝书一致 树的重心 概念: 一颗树中的一个节点其最大子树的节点树最小 解法:对与每个节点求他儿子的\(size\) ,上方子树的节点个数为\(n-size_u\) ...

  4. 斜率优化DP学习笔记

    先摆上学习的文章: orzzz:斜率优化dp学习 Accept:斜率优化DP 感谢dalao们的讲解,还是十分清晰的 斜率优化$DP$的本质是,通过转移的一些性质,避免枚举地得到最优转移 经典题:HD ...

  5. 动态 DP 学习笔记

    不得不承认,去年提高组 D2T3 对动态 DP 起到了良好的普及效果. 动态 DP 主要用于解决一类问题.这类问题一般原本都是较为简单的树上 DP 问题,但是被套上了丧心病狂的修改点权的操作.举个例子 ...

  6. [总结] 动态DP学习笔记

    学习了一下动态DP 问题的来源: 给定一棵 \(n\) 个节点的树,点有点权,有 \(m\) 次修改单点点权的操作,回答每次操作之后的最大带权独立集大小. 首先一个显然的 \(O(nm)\) 的做法就 ...

  7. 插头DP学习笔记——从入门到……????

    我们今天来学习插头DP??? BZOJ 2595:[Wc2008]游览计划 Input 第一行有两个整数,N和 M,描述方块的数目. 接下来 N行, 每行有 M 个非负整数, 如果该整数为 0, 则该 ...

  8. 树形$dp$学习笔记

    今天学习了树形\(dp\),一开始浏览各大\(blog\),发现都\(TM\)是题,连个入门的\(blog\)都没有,体验极差.所以我立志要写一篇可以让初学树形\(dp\)的童鞋快速入门. 树形\(d ...

  9. 斜率优化dp学习笔记 洛谷P3915[HNOI2008]玩具装箱toy

    本文为原创??? 作者写这篇文章的时候刚刚初一毕业…… 如有错误请各位大佬指正 从例题入手 洛谷P3915[HNOI2008]玩具装箱toy Step0:读题 Q:暴力? 如果您学习过dp 不难推出d ...

随机推荐

  1. Ubuntu上好用的截图工具——flameshot

    前言   堪称完美的截图工具--flameshot,windows上人们习惯性的使用QQ自带的截图工具Ctrl+Alt+A或者WeChat自带的截图工具Alt+A,若您是一位使用聊天工具截图多年的&q ...

  2. Go GRPC 入门(一)

    前言 微服务相关 使用 GRPC 通讯的 Golang 微服务入门 举例写一个微服务,接收网址发送请求获取返回结果返回 正文 安装工具 安装 protobuf 这是 proto 文件的编译器 点我下载 ...

  3. 【Spring】Spring中的Bean - 2、Baen的实例化 (构造器、静态工厂、实例工厂)

    Bean的实例化 文章目录 Bean的实例化 构造器实例化 静态工厂方式实例化 实例工厂方式实例化 简单记录-Java EE企业级应用开发教程(Spring+Spring MVC+MyBatis)-S ...

  4. Git软件安装过程

    Git程序安装过程 官网: https://git-scm.com/ 下载: https://git-scm.com/downloads 我的操作系统是 Windows + 64位的 https:// ...

  5. kafka安装流程

    本文是作者原创,版权归作者所有.若要转载,请注明出处. 安装前的环境准备 1.由于Kafka是用Scala语言开发的,运行在JVM上,在安装之前需要先安装JDK(省略) 2.kafka依赖zookee ...

  6. Linux删除文件后磁盘目录不释放

    今天测试oracle数据库的时候,把表空间连带内容和数据文件一并删除了,但是删除之后,查看数据文件不存在了,但是目录的带下没有释放 SQL> drop tablespace users incl ...

  7. linux设备

    设备初始化时同样要执行一个device_register函数,该函数传入一个struct device *类型的指针,因此要定义一个struct device类型的变量作为我们的设备. struct ...

  8. synchronized的jvm源码分析聊锁的意义

    上篇写完了ReentrantLock源码实现,从我们的角度分析设计锁,在对比大神的实现,顺道拍了一波道哥的马屁,虽然他看不到,哈哈.这一篇我们来聊一聊synchronized的源码实现,并对比reen ...

  9. JavaScript中的深拷贝和浅拷贝!【有错误】还未修改!请逛其他园子!

    JavaScript中的深拷贝和浅拷贝! 浅拷贝 1.浅拷贝只是拷贝一层,更深层次对象级别的只拷贝引用.{也就是拷贝的是地址!简而言之就是在新的对象中修改深层次的值也会影响原来的对象!} // 2.深 ...

  10. Vue中:error 'XXXXX' is not defined no-undef解决办法

    Vue中:error 'XXXXX' is not defined no-undef解决办法 报错内容: × Client Compiled with some errors in 7.42s √ S ...