首页 > 其他分享 >SOS DP(子集 DP)

SOS DP(子集 DP)

时间:2023-08-06 22:12:38浏览次数:36  
标签:int mask SOS 子集 101 subseteq DP

Part 1:前置知识

1、状压 DP

2、基本的位运算操作

Part 2:SOS DP

(以下的内容大部分翻译至CF上的原文

1、例题引入

给定一个含 \(2^N\) 个整数的集合 \(A\),我们需要计算:\(\forall x \subseteq A\),\(x\) 中所有元素 \(i\) 的 \(A[i]\) 的和,即求:

\[F[mask]=\sum\limits_{i \subseteq mask}^{}{A[i}] \]

2、解题思路

法一:暴力枚举

  • 我们可以枚举每一个 \(mask\),再枚举集合中的所有元素 \(i\),判断 \(i\) 是属于集合 \(mask\)。这样做的时间复杂度为 \(O(4^N)\)

  • 代码

for(int mask=0; mask<(1<<N); mask++)
  	for(int i=0; i<(1<<N); i++)
		if((mask&i)==i)
		  	F[mask]+=A[i];

法二:枚举子集

  • 对于任意 \(mask\),如果它做的二进制位上有 \(k\) 个 \(1\),那么它就有 \(2^k\) 个子集,我们只需遍历这些子集便可。

    时间复杂度为 \(O(\sum\limits_{k=0}^{N}{\tbinom{N}{k}2^k})=O((1+2)^N)=O(3^N)\)。(可由二项式定理证明)

  • 代码

for(int mask=0; mask<(1<<N); mask++)
{
	F[mask]=A[0];
	for(int i=mask; i>0; i=(i-1)&mask)
		F[mask]+=A[i];
}

法三:SOS DP

  • 在我们之前的方法中存在明显的缺陷:当一个状态的二进制位上有 \(k\) 个 \(0\) 时,它将被访问 \(2^k\) 次,存在重复的计算。

    而产生这种现象的原因就是:我们没有在 \(A[x]\) 被不同 \(F[mask]\) 利用时建立一定的联系。我们应添加另一个状态来避免上述的重复计算。

  • 我们定义状态 \(S(mask)=\{x|x\subseteq mask\}\)。现在我们把这个集合划分为不相交的组。

    设\(S(mask,i)=\{x|x\subseteq mask,\:mask⊕x<2^i+1\}\),表示只有第 \(i\) 位以及更低位与 \(mask\) 不同的 \(x\) 的集合。

    举个例子:\(S(\)101\(1010,3)=\{\)101\(1010,\)101\(0010,\)101\(1000,\)101\(0000\}\) 。其中 \(1010\) 即为 \(mask\) 的第 \(3\) 位至第 \(0\) 位,集合中的元素的加粗部分应与 \(mask\) 保持一致。

  • 现在让我们尝试将 \(mask\) 与 \(x\) 建立联系,下面分两种情况讨论:

    1. \(mask\) 的第 \(i\) 位是 \(0\)

      不难发现,\(mask\) 与 \(x\) 的第 \(i\) 位均为 \(0\)。因此 \(x\) 仅有第 \(0\) 至 \(i-1\) 位与 \(mask\) 不同,故有 \(S(mask,i)=S(mask,i-1)\)

    2. \(mask\) 的第 \(i\) 位是 \(1\)

      那么 \(S(mask,i)\) 就由两部分组成:

      \((1)\:\) \(x\) 的第 \(i\) 位为 \(0\),即为 \(S(mask⊕2^i,i-1)\)

      \((2)\:\) \(x\) 的第 \(i\) 位为 \(1\),即为 \(S(mask,i-1)\)

  • 综上,可以得出结论

    \[S(mask,i)=\begin{cases}S(mask,i-1)&&i^{th}\:bit \:0\\S(mask,i-1)+S(mask⊕2^i,i-1)&&i^{th}\:bit\:1\end{cases} \]

    不难计算,这种做法的时间复杂度为 \(O(N2^N)\)

  • 代码(二维版)

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

标签:int,mask,SOS,子集,101,subseteq,DP
From: https://www.cnblogs.com/xishanmeigao/p/17610172.html

相关文章

  • FreeSWITCH添加自定义endpoint之媒体交互
    操作系统:CentOS7.6_x64FreeSWITCH版本:1.10.9 之前写过FreeSWITCH添加自定义endpoint的文章:https://www.cnblogs.com/MikeZhang/p/fsAddEndpoint20230528.html今天记录下endpoint媒体交互的过程并提供示例代码及相关资源下载,本文涉及示例代码和资源可从如下渠道获取:关......
  • 力扣-划分为k个相等的子集
    1.问题描述给定一个整数数组 nums和一个正整数k,找出是否有可能把这个数组分成k个非空子集,其总和都相等。示例1:输入:nums=[4,3,2,3,5,2,1],k=4输出:True2.说明有可能将其分成4个子集(5),(1,4),(2,3),(2,3)等于总和。输入说明:首先输入nums数组的长度n,然后输入n个......
  • [Microsoft Azure] 使用 Microsoft Azure VM 快速创建宝塔面板并安装 WordPress 博客
     视频演示:[MicrosoftAzure]使用MicrosoftAzureVM快速创建宝塔面板并安装WordPress博客-Bilibili概述:创建AzureVM配置AzureVM安装宝塔面板安装WordPress步骤1:创建AzureVM首先,登录到MicrosoftAzure门户(https://portal.azure.com/)并使用您的Micros......
  • dperf minio 团队开源的磁盘性能测试工具
    dperfminio团队开源的磁盘性能测试工具基于golang开发,使用简单,类似的有fio说明相比fiodperf没有那么多的参数,实际上dperf核心似乎主要是为了方便minio使用的,但是对于日常中需要测试一些磁盘问题也是可以的,可以用来发现磁盘的瓶颈参考资料https://github.com/minio/dpe......
  • 【ACM专项练习#03】打印图形、栈的合法性、链表操作、dp实例
    运营商活动题目描述小明每天的话费是1元,运营商做活动,手机每充值K元就可以获赠1元,一开始小明充值M元,问最多可以用多少天?注意赠送的话费也可以参与到奖励规则中输入输入包括多个测试实例。每个测试实例包括2个整数M,K(2<=k<=M<=1000)。M=0,K=0代表输入结束。输出对于每个测试实......
  • Cilium系列-13-启用XDP加速及Cilium性能调优总结
    系列文章Cilium系列文章前言将Kubernetes的CNI从其他组件切换为Cilium,已经可以有效地提升网络的性能.但是通过对Cilium不同模式的切换/功能的启用,可以进一步提升Cilium的网络性能.具体调优项包括不限于:启用本地路由(NativeRouting)完全替换KubeProxyI......
  • ysoserial中的URLDNS利用链代码审计
    ysoserial中的URLDNS利用链代码审计一.避坑我使用了jdk1.8的版本,因为在使用jdk1.7版本的时候出现了如下报错java:程序包sun.rmi.server不存在之后问chatgpt之后我发现不知为什么我的jdk1.7里面没有rt.jar,所以我换成了jdk1.8二.环境搭建1.下载源码https://github.com......
  • UDP 编程
    UDP编程#include<sys/socket.h>//可以发送或接收一个长度为0的数据报ssize_trecvfrom(intsockfd,void*buf,size_tnbytes,intflags,//常与recvsendrecvmsgsendmsg配合structsockaddr*from,sockl......
  • dp优化
    dp数位dp模板//下标从1开始统计初始化均1开始lldfs(intpos,intpre_num,intc,intflag){ intmax_number; if(pos<=0)returnc==0; if(!flag&&dp[pos][pre_num][c]!=-1)returndp[pos][pre_num][c]; if(flag)max_number=upper[pos]; elsemax_number=9; llret=......
  • ESF、Z-projection和M2DP论文阅读
    ESFTitle标题【2011ICRB】ESF:EnsembleofShapeFunctionsfor3DObjectClassification.【code】简介引入了一种新的形状描述符ESF(EnsembleofshapeFunctions),这是一种基于描述部分点云表面距离、角度和面积分布的三种不同形状函数的全局形状描述符。ESF方法在定义......