SoS-DP 学习笔记

reference: https://codeforces.com/blog/entry/45223

前置技能: 状态压缩 DP

SoS-DP 全称是 Sum over Subsets Dynamic Programming,即子集和 DP,属于状态压缩 DP 中的一个经典问题的优化。

1. 问题引入

f [ s ] = ∑ i ∈ s a [ i ] f[s]=\sum\limits_{i\in s} a[i] f[s]=isa[i] f [ i ] = ∑ i ∈ s a [ s ] f[i]=\sum\limits_{i\in s} a[s] f[i]=isa[s],我们拿出第一个问题来讨论。

2. 朴素写法

O ( 4 n ) \mathcal{O}(4^n) O(4n) 暴力枚举:

int up = 1 << n;
for (int s = 0; s < up; s++) {
	for (int i = 0; i < up; i++) {
		if (s & i == i) f[s] += a[i];
	}
}
3. 稍微优化

O ( 3 n ) \mathcal{O}(3^n) O(3n) 枚举子集:

for (int s = 0; s < up; s++) {
	f[s] = a[0];
	for (int i = s; i > 0; i = (i-1)&s) f[s] += f[i];
}
4. 使劲优化

f [ s ] [ i ] f[s][i] f[s][i] 表示 x & s = x x\&s=x x&s=x x ⊕ s < 2 i + 1 x\oplus s<2^{i+1} xs<2i+1 a [ x ] a[x] a[x] 的和,有 f [ s ] [ i ] = f [ s ] [ i − 1 ] + f [ s ⊕ 2 i ] [ i − 1 ] f[s][i]=f[s][i-1]+f[s\oplus2^i][i-1] f[s][i]=f[s][i1]+f[s2i][i1],转移图如下:

img

那么我们就有了下面的写法:

// iterative version
for (int s = 0; s < up; s++) {
	dp[s][-1] = a[s];
	for (int i = 0; i < n; i++) {
		if (s & (1 << i)) dp[s][i] = dp[s][i-1] + dp[s^(1<<i)][i-1];
		else dp[s][i] = dp[s][i-1];
	}
	f[s] = dp[s][n-1];
}
// memory optimized version
for (int s = 0; s < up; s++) f[s] = a[s];
for (int i = 0; i < n; i++) {
	for (int s = 0; s < up; s++) {
		if (s & (1 << i)) f[s] += f[s^(1<<i)]; // f[s^(1<<i)] += f[s]
	}
}

可以证明这个时间复杂度是 O ( n ⋅ 2 n ) \mathcal{O}(n\cdot2^n) O(n2n) 非常优秀。

5. 例题

Codeforces - 449D

Codeforces - 1028F

Codeforces - 1234F

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
-bash: SOS: command not found的错误提示意味着在当前的Linux环境中找不到名为SOS的命令。这可能是由于以下原因之一导致的: 1. 命令不存在:首先,请确保你输入的命令是正确的。检查是否拼写错误或者命令不存在。如果你确定命令存在,那么可能是由于环境变量配置问题导致的。 2. 环境变量配置问题:检查你的环境变量配置是否正确。特别是检查$PATH变量,它决定了shell在哪些目录下寻找命令或工具。如果$PATH没有正确设置,那么系统将无法找到命令。你可以通过运行`echo $PATH`命令来查看当前的$PATH值。确保所需的目录包含在$PATH中。 解决这个问题的方法有: 1. 检查命令是否存在:首先,确保你输入的命令是正确的,并且在当前的Linux环境中存在。你可以尝试使用`which`命令来查找命令的路径,例如`which SOS`。 2. 检查环境变量配置:运行`echo $PATH`命令来查看当前的$PATH值。确保所需的目录包含在$PATH中。如果没有包含,你可以通过编辑`~/.bashrc`或`~/.bash_profile`文件来添加目录到$PATH中。例如,如果你的命令在`/usr/local/bin`目录下,你可以将以下行添加到`~/.bashrc`文件中: ```shell export PATH=$PATH:/usr/local/bin ``` 然后运行`source ~/.bashrc`命令使更改生效。 3. 重新登录或重启终端:有时候,环境变量的更改需要重新登录或重启终端才能生效。尝试重新登录或重启终端,然后再次尝试运行命令。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值