状压dp 理论例题 详解

状压dp

四川2005年省选题:互不侵犯

首先我们可以分析一下,按照我们普通的思路,就是用搜索,枚举每一行的每一列,尝试放下一个国王,然后标记,继续枚举下一行

那么,我们的时间复杂度就拥有了:
O ( 9 9 ) O(9^9) O(99)
计算方法:

因为是 n × n n\times n n×n 的棋盘,所以每行都会有至多9列( n ≤ 9 n\le 9 n9

然而我们每行都会有 n n n 种状态,所以我们的时间复杂度就是 O ( n n ) O(n^n) O(nn) ,即 O ( 9 9 ) O(9^9) O(99)

不过嘛——

所以我们是肯定不能采用的

这个时候,我们就需要学到一个 鬼东西 ——状态压缩dp!!

状压dp介绍——

所谓状压,字面翻译,就是把 复杂的状态 简化为 简洁的n进制数来表示

例如这道题

因为dp的状态转移,无非就是放和不放,所以我们就可以很容易地想到,用二进制的01串来表示,例子——

010001000

表示在第2列和第6列放国王,其余不放。

( 010001000 ) 2 (010001000)_2 (010001000)2 = ( 136 ) 10 (136)_{10} (136)10

因为 n ≤ 9 n\le 9 n9 ,所以这个数 ≤ 2 9 \le 2^9 29 ≤ 512 \le 512 512

那么我们需要进行一下判断,即满足什么条件时,可以放置这个国王

条件判断:

首先因为是二维的关系,我们先来判断行的关系,即一行一行地判断,看看上一行所放置的国王,限制了这一行哪些国王的放置

扫雷都玩过吧,附近的八个格子,设国王放置在 (x,y) 的地方,我们将它简化为以下关系:(x为行,y为列)
( x − 1 , y − 1 )       ( x − 1 , y )       ( x , y + 1 ) ( x , y − 1 )       ( x , y )       ( x , y + 1 ) ( x + 1 , y − 1 )       ( x + 1 , y )       ( x + 1 , y + 1 ) (x-1,y-1)\ \ \ \ \ (x-1,y)\ \ \ \ \ (x,y+1) \\ (x,y-1)\ \ \ \ \ (x,y)\ \ \ \ \ (x,y+1) \\ (x+1,y-1)\ \ \ \ \ (x+1,y)\ \ \ \ \ (x+1,y+1) (x1,y1)     (x1,y)     (x,y+1)(x,y1)     (x,y)     (x,y+1)(x+1,y1)     (x+1,y)     (x+1,y+1)

显然,如果上一行的 i 列放置了国王,那么下一行的 i-1,i,i+1 都不可以放置

那么如何判断呢

我们不难想到二进制的 左移右移运算符 ,目的是可以将目标 i 移到左于右的地方,进行判断

判断方法:

如果我们这一行的第 j 列需要放国王,那么上一行的 (i<<1),(i>>1),i 都不可为1,那么我们就可以运用位运算符 & 。有一位是1答案就为1,换句话说,只要 上下行同列放了两个国王 ,就不合法

再来说下列的关系

如果在同一列,左移右移旁边都没有,则是合法的(具体可以联系行的关系进行思考)

那么我们应该如何设用来dp的 f 数组, 状态转移方程 又该怎么写呢

我们不难想到可以一行一行的枚举(上文已提到),即设 f 数组 f[i][j][l] 表示现在在第 i 行,已经放了 j 个国王,所有方案为 l (这就是状压dp的精髓所在)

状态转移方程:

f ( i , j , l ) = ∑ f ( i − 1 , x , l − s t a ( j ) ) f(i,j,l)=\sum f(i-1,x,l-sta(j)) f(i,j,l)=f(i1,x,lsta(j))

代码(加过注释的):

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN=15,MAXM=85,MAXS=(1<<9)+5;
int n,k;
ll f[MAXN][MAXM][MAXS],ans;
int cnt,tmp,tot;
int num[MAXS],s[MAXS];
int s1,s2;
int main(){
	scanf("%d%d",&n,&k);
	f[0][0][0]=1;
	for(int i=0;i<(1<<n);i++)
	{
		cnt=0,tmp=i;
		while(tmp)
		{
			if(tmp&1) ++cnt;//cnt统计i的二进制有放了多少国王
			tmp=tmp>>1;//继续枚举 
		}
		num[i]=cnt;//num[i]表示第i种状态有num[i]个国王放在那里 
		if(!(((i<<1)|(i>>1))&i)) s[++tot]=i;//判断行内放国王合不合法,比较抽象 
	}
	for(int i=1;i<=n;i++)//遍历每一行 
	{
		for(int j=1;j<=tot;j++)//枚举这一行每种可能的状态 
		{
			s2=s[j];//s2代表这一行的状态 
			for(int l=1;l<=tot;l++)//前一行的每种状态 
			{
				s1=s[l];//s1代表上一行的状态 
				if(!(s1&s2)&&(!((s1<<1)&s2))&&(!((s1>>1)&s2)))//行间的限制判断 
					for(int a=0;a<=k;a++)
						if(a-num[s2]>=0)
							f[i][a][s2]+=f[i-1][a-num[s2]][s1];
			}
		}
	}
	for(int i=1;i<=tot;i++)
		ans+=f[n][k][s[i]];
	printf("%lld\n",ans);
	return 0;
}

AC记录

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/596930.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Vue 介绍

【1】前端发展史 前端的发展史可简述为&#xff1a; 从最初的静态页面编写&#xff0c;依赖后端模板渲染逐步演化为通过JavaScript&#xff08;特别是Ajax技术&#xff09;实现前后端分离&#xff0c;使得前端能够独立地加载数据和渲染页面随后&#xff0c;Angular、React、Vu…

Ubuntu20.04右键打不开终端

今天用virtualbox安装了ubuntu20.04 问题&#xff1a;右键打开终端&#xff0c;怎么也打开不了&#xff01; 点了也没反应&#xff0c;或者鼠标转小圈圈&#xff0c;然后也没有反应… 解决方法&#xff1a; 1、Ctrl Alt F6 先切换到终端访问界面 mac电脑 Ctrl Alt F6 …

ADS基础教程9-理想模型和厂商模型实现及对比

目录 一、概要二、厂商库使用1.新建cell2.调用厂商库中元器件3.元器件替换及参数选择4.完成参数选择5.导入子图 三、仿真实现注意事项 一、概要 本文将介绍在ADS中调用厂商提供的库&#xff0c;来进行原理图仿真&#xff0c;并实现与ADS系统提供的理想元器件之间的比较。 二、…

docker安装redis命令及运行

docker安装redis&#xff1a; docker run -d -p 6379:6379 --name redis redis:latest -d: 以 守护进程模式 运行容器&#xff0c;容器启动后会进入后台运行&#xff0c;并脱离当前命令行会话。 -p: 显示端口号。 -p 6379:6379: 将容器内部的 6379 端口映射到宿主机 6379 端…

力扣每日一题-去掉最低工资和最高工资后的工资平均值-2024.5.3

力扣题目&#xff1a;去掉最低工资和最高工资后的工资平均值 开篇 题目链接: 1491.去掉最低工资和最高工资后的工资平均值 题目描述 代码思路 太简单了。先利用sort排序对数组进行从小到大排序&#xff0c;然后计算时数组最小值和最大值不要加进去即可。 代码纯享版 clas…

【go项目01_学习记录06】

学习记录 1 使用中间件1.1 测试一下1.2 push代码 2 URI 中的斜杆2.1 StrictSlash2.2 兼容 POST 请求 1 使用中间件 代码中存在重复率很高的代码 w.Header().Set("Content-Type", "text/html; charsetutf-8")统一对响应做处理的&#xff0c;我们可以使用中…

低代码优于无代码?

从1804年打孔式编程出现&#xff0c;编程语言至今已经存在了200多年。而从50年代以来&#xff0c;新的编程语言也不断涌现&#xff0c;现在已经有250多种了。这就意味着&#xff0c;开发人员最需要习惯的事情就是不断改变。 编程界最近的一个变化是集成开发环境&#xff08;IDE…

一起了解开源自定义表单的优势表现

随着社会的进步和科技的发展&#xff0c;越来越多的中小企业希望采用更为先进的软件平台&#xff0c;助力企业实现高效率的流程化管理。低代码技术平台、开源自定义表单已经慢慢走入大众视野&#xff0c;成为一款灵活、高效的数字化转型工具。流辰信息专注于低代码技术平台的研…

PyTorch机器学习实现液态神经网络

大家好&#xff0c;人工智能的发展催生了神经网络这一强大的预测工具&#xff0c;这些网络通过数据和参数优化生成预测&#xff0c;每个神经元像逻辑回归门一样工作。结合反向传播技术&#xff0c;模型能够根据损失函数来调整参数权重&#xff0c;实现自我优化。 然而&#xf…

【Linux】掌握Linux系统编程中的权限与访问控制

&#x1f49e;&#x1f49e; 前言 hello hello~ &#xff0c;这里是大耳朵土土垚~&#x1f496;&#x1f496; &#xff0c;欢迎大家点赞&#x1f973;&#x1f973;关注&#x1f4a5;&#x1f4a5;收藏&#x1f339;&#x1f339;&#x1f339; &#x1f4a5;个人主页&#x…

小猫咪邮件在线发送系统源码v1.1,支持添加附件

内容目录 一、详细介绍二、效果展示1.部分代码2.效果图展示 三、学习资料下载 一、详细介绍 小猫咪邮件在线发送系统源码v1.1&#xff0c;支持添加附件 一款免登录发送邮件&#xff0c;支持发送附件&#xff0c;后台可添加邮箱,前台可选择发送邮箱 网站数据采取本地保存&…

算法课程笔记——如何倍增

快速幂 读入量大于1e5不要用cin读入&#xff0c;要用也要关闭同步流 第i个o次方的父亲 #include<bits/stdc.h>usingnamespacestd; #definemaxn 110000#definell long longintn, a[maxn], f[maxn][40]; intquery(intl, intr){intk (int)(log((r - l 1) * 1.0) / log(2.0…

从OutputStream类看Java中的IO流操作

哈喽&#xff0c;各位小伙伴们&#xff0c;你们好呀&#xff0c;我是喵手。运营社区&#xff1a;C站/掘金/腾讯云&#xff1b;欢迎大家常来逛逛 今天我要给大家分享一些自己日常学习到的一些知识点&#xff0c;并以文字的形式跟大家一起交流&#xff0c;互相学习&#xff0c;一…

一般显卡3d建模渲染够用吗?3d云渲染助力

3D建模和渲染对计算机硬件有较高要求&#xff0c;特别是显卡。显卡的性能直接影响渲染速度&#xff0c;低端和高端显卡在渲染效率上存在显著差异。对于追求快速渲染的用户&#xff0c;高端显卡是首选。那么&#xff0c;4050显卡是否能够满足3D建模渲染的需求呢?下面我们来探讨…

CSS悬浮动画

<button class"btn">悬浮动画</button>.btn {position: absolute;top: 50%;left: 50%;transform: translate(-50%, -50%);padding: 10px 20px;width: 200px;height: 50px;background-color: transparent;border-radius: 5px;border: 2px solid powderblu…

第78天:WAF攻防-菜刀冰蝎哥斯拉流量通讯特征绕过检测反制感知

目录 案例一&#xff1a; 菜刀-流量&绕过&特征&检测 菜刀的流量特征 案例二&#xff1a;冰蝎-流量&绕过&特征&检测 冰蝎使用教程 冰蝎的流量特征 案例三&#xff1a; 哥斯拉-流量&绕过&特征&检测 哥斯拉使用教程 哥斯拉的流量特征…

二手车买卖求购置换租车微信抖音小程序开源版开发

二手车买卖求购置换租车微信抖音小程序开源版开发 二手车置换平台小程序系统&#xff0c;为买家和卖家提供了一个交流和交易的平台 Uniapp&#xff0c;基于Uniapp开发&#xff0c;仅支持编译微信小程序和抖音小程序 车辆发布&#xff0c;自主发布车辆信息。 圈子交流&#xff…

自动驾驶主流芯片及平台架构(二)特斯拉自动驾驶芯片平台介绍

早期 对外采购mobileye EyeQ3 芯片摄像头半集成方案&#xff0c;主要是为了满足快速量产需求&#xff0c;且受制于研发资金不足限制&#xff1b; 中期 采用高算力NVIDIA 芯片平台其他摄像头供应商的特斯拉内部集成方案&#xff0c;mobileye开发节奏无法紧跟特斯拉需求&#xff…

嵌入式系统应用-拓展-FLASH之操作 SFUD (Serial Flash Universal Driver)之KEIL移植

1 SFUD介绍 1.1 初步介绍 SFUD 是一个开源的串行 SPI 闪存通用驱动库。由于市面上有各种类型的串行闪存设备&#xff0c;每种设备都具有不同的规格和指令&#xff0c;因此 SFUD 的设计目的是解决这些差异。这使得我们的产品可以支持不同品牌和规格的闪存&#xff0c;增强了软…

任意文件读取rce记录

1.跨目录上传 对某系统进行测试时&#xff0c;发现有一处上传附件的功能&#xff0c;常规上传个文件试试 发现返回包返回了重命名后的文件名称和系统的绝对路径 继续看上传的文件 只有一个预览的功能&#xff0c;访问直接下载该文件&#xff0c;并没有什么用&#xff0c;请求链…