【算法每日一练]-动态规划(保姆级教程 篇17 状态压缩)

 目录

今日知识点:

把状态压缩成j,dp每行i的布置状态,从i-1和i-2行进行不断转移

把状态压缩成j,dp每行i的布置状态,从i-1行进行状态匹配,然后枚举国王数转移

 POJ1185:炮兵阵地

思路:

题目:互不侵犯

思路:


        

        

 POJ1185:炮兵阵地

在N*M(N<100,M<10)的地图上布置炮兵,H格子为山地不能布置,P格子为平原可以布置。炮兵的攻击范围是沿横向左右各两格,沿纵向上下个两格子
炮兵之间不能误伤。问在整个地图中最多能拜访多少个炮兵?
5 4
PHPP
PPHH
PPPP
PHPP
PHHP

        

思路:

还是那么句话,每个格子都有2种状态,如果搜索就要把所有结果都跑出来,所以只能使用状压dp 。      

而且方程的转移和上一行的状态有关,但是状态又太多了,故要状态压缩。

首先要对行进行状态压缩(对列的话太大了,枚举2^100还不如不压缩呢),我们每次确定行的状态都需要考虑:
1.横向方案    2.横向方案是否和地图匹配     3.是否和i-1行i-2行冲突
设置dp[i][j][k]表示第i行为第j状态,第i-1行为第k状态时 对应的前i行放置的最大炮兵数。
转移方程:dp[i][j][k]=max(dp[i][j][k],dp[i-1][k][t]+num[j]);(num是对应状态的炮兵个数)

(j是第i行的方案,k是第i-1行的方案,t是i-2行的方案)
存每行的可能状态:左右相邻1个间隔和2个间隔都不能炮兵(就是可能的横向方案)
存图:(1,1)开始存。0表示平原,1表示山地,那么在放置的时候不能出现同1(在山地放炮兵),所以x&y=0是合法的(保证合法的是0就行了)
是否冲突:第i行和第i-1行,第i-2行 不能出现有一列同1(两行都放炮兵),所以x&y=0是合法的

        
【注意】:外面每行i循环一次,其次里面是第i行的每个状态j循环一次(找到合适的j),然后是第i-1行的每个状态k循环一次(供第i行找到合适的k),
接着是第i-2行的每个状态t循环一次(供第i-1行找到合适的t)

#include <bits/stdc++.h>
using namespace std;
int n,m,top;
char mp[110][20];
int num[70];//num存放状态对应的炮兵个数
int ok[70],cur[70];//ok表示横向可能的方案,cur是我们存的地图行
int dp[110][70][70];bool check(int x){if(x&(x<<1))return 0;//相邻1间隔是否合法if(x&(x<<2))return 0;//相邻2间隔是否合法return 1;
}void init(){//统计所有的可能合法状态,最多60种top=0;for(int i=0;i<(1<<m);i++){//不能取等,不能取等!!!if(check(i))ok[top++]=i;}
}int count(int x){//统计x二进制中1的个数int cnt=0;while(x){if(x&1)cnt++;x=x>>1;}
//	while(x){//这个更快
//		cnt++;
//		x&=(x-1);
//	}	return cnt;
}int solve(){int ans=0;memset(dp,-1,sizeof(dp));for(int j=0;j<top;j++){//初始化第一行的状态num[j]=count(ok[j]);//记录每个正确状态的炮兵个数if(!(ok[j]&cur[1])){//和地图匹配dp[1][j][0]=num[j];//第一行状态为j,上一行状态为0(知道为啥从(1,1)开始初始化了把)ans=max(ans,dp[1][j][0]);}}for(int i=2;i<=n;i++){//处理每一行for(int j=0;j<top;j++){//遍历第i行的可能方案if(ok[j]&cur[i])continue;//是否和地图匹配for(int k=0;k<top;k++){//遍历第i-1行的可能方案if(ok[j]&ok[k])continue;//此行和上一行是否匹配(不用再判断和地图是否匹配,不匹配dp是-1,不影响的)for(int t=0;t<top;t++){//遍历上二行可能方案if(ok[j]&ok[t])continue;//此行和上二行是否匹配dp[i][j][k]=max(dp[i][j][k],dp[i-1][k][t]+num[j]);}if(i==n)ans=max(ans,dp[i][j][k]);//不要放在外面套3个for取max}}}return ans;
}
int main(){while(cin>>n>>m){init();for(int i=1;i<=n;i++){scanf("%s",mp[i]+1);//加1是为了从1下标开始存}for(int i=1;i<=n;i++){cur[i]=0;for(int j=1;j<=m;j++){if(mp[i][j]=='H')//同样的,不能放的地方存1cur[i]+=(1<<(m-j));}}cout<<solve();}
}

        

        

题目:互不侵犯

思路:

可以看到和炮兵阵地题非常像,跑不了是状压dp。

还是那句话,每个方格都有两种状态,搜索的话必然是要全部搜索一下,放弃吧(况且,不谈超时,你真的把本道题的dfs其实也够呛的)。

设置dp[i][j][k]表示第i行为j状态时已经放了k个国王对应的方案数。

转移方程:dp[i][j][k]=dp[i-1][i-1行所有的合法状态][k-对应状态的国王数];

然后就是对状态的处理:

行内状态:我们要保证相与出0合法,非0不合法。那么对s行,

有:(((s<<1)&s==0)&&((s>>1)&s)==0)算合法,

等价于这个写法:(((s<<1)|(s>>1))&s)==0。   千万别少写红色括号!!!
行间状态:((s2&s1==0)&&((s2>>1)&s1==0)&&((s2<<1)&s1)==0)才算合法,

等价于:(((s2|(s2>>1)|(s2<<1))&s1)==0。

循环方式:首先是每行,然后选择该行状态,然后是上行状态,判断两行状态是否匹配,如果匹配就枚举国王数,最后转移方程!

#include <bits/stdc++.h>
using namespace std;
int num,n,k;//ok存正确的行状态,cnt存状态对应的国王数
long long dp[10][100][2000],cnt[2000],ok[2000];
int main(){cin>>n>>k;for(int s=0;s<(1<<n);s++){//遍历出所有的正确状态iint tot=0,tmp=s;while(tmp){if(tmp&1)tot++;tmp>>=1;}cnt[s]=tot;//存每个状态的国王数if((((s<<1)|(s>>1))&s)==0) ok[++num]=s;}dp[0][0][0]=1;for(int i=1;i<=n;i++){//从第一行开始转移for(int ss1=1;ss1<=num;ss1++){int s1=ok[ss1];//选择第一行的状态for(int ss2=1;ss2<=num;ss2++){int s2=ok[ss2];//选择上一行的状态if(((s2|(s2<<1)|(s2>>1))&s1)==0){//如果这两行状态合法for(int j=0;j<=k;j++){//对国王数进行枚举转移if(j-cnt[s1]>=0)dp[i][j][s1]+=dp[i-1][j-cnt[s1]][s2];}}}}}long long ans=0;for(int i=1;i<=num;i++)ans+=dp[n][k][ok[i]];cout<<ans;
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

TRIZ理论在创新实践中的优势体现在哪些地方?

当下&#xff0c;创新已成为推动企业和社会发展的关键动力。TRIZ&#xff0c;即发明问题解决理论。作为一套系统化的创新方法论&#xff0c;它通过分析大量专利和发明案例&#xff0c;总结出一套解决问题的通用方法和流程。那么&#xff0c;TRIZ理论在创新实践中的优势具体体现…

振弦采集仪在地下水位监测中的可行性研究与实践

振弦采集仪在地下水位监测中的可行性研究与实践 地下水位的监测对于水资源管理和地下水环境保护具有重要意义。传统的地下水位监测方法主要包括井水位计、压力传感器和雨水入渗监测等。然而&#xff0c;这些方法存在着一些局限性&#xff0c;如需要人工维护、监测周期长、监测…

KylinOS银河麒麟安装部署AI服务

KylinOS银河麒麟安装部署AI服务&#xff08;CPU版本&#xff09; 查看操作系统 [jnapp8160fcc7cf1b ~]$ nkvers ############## Kylin Linux Version ################# Release: Kylin Linux Advanced Server release V10 (Lance)Kernel: 6.2.0-36-genericBuild: Kylin Linux…

vue ts 应用梳理

文章目录 前言一、页面传值1.1 [props](https://cn.vuejs.org/guide/components/props.html)1.2 [emit](https://cn.vuejs.org/guide/components/events.html)1.3 [store](https://pinia.vuejs.org/zh/getting-started.html) 二、实时计算2.1 [watch](https://cn.vuejs.org/gui…

ArcGISPro 如何升级某项Python库且不影响其运行

升级包scipy 可以看出scipy当前版本是1.6.2 利用不依赖包升级 pip install --upgrade scipy --no-deps 结果 但是显示还是之前的版本

Linux系统下关闭Java进程

关闭Java进程具体分为两步&#xff1a; 1.ps查进程ID 2.kill杀进程 具体的命令如下&#xff1a; ps查进程ID&#xff1a;ps -ef | grep java kill杀进程&#xff1a;kill -9 对应进程号 linux下解除被占用的端口号&#xff1a; 1.查看8088端口是否被占用&#xff1a; netsta…

【教程】iOS Swift应用加固

&#x1f512; 保护您的iOS应用免受恶意攻击&#xff01;在本篇博客中&#xff0c;我们将介绍如何使用HTTPCORE DES加密来加固您的应用程序&#xff0c;并优化其安全性。通过以下步骤&#xff0c;您可以确保您的应用在运行过程中不会遭受数据泄露和未授权访问的风险。 摘要 …

PD虚拟机软件下载:在 Mac 上流畅运行 Windows 游戏!

本想一台 MacBook 走天下&#xff0c;奈何有些软件仅提供了 Windows 端&#xff0c;在 macOS 上打不开 EXE 文件&#xff0c;比如炒股软件、会计软件、游戏、工科专业软件等。 由于苹果芯片架构的变化&#xff0c;新款 Mac 想要安装双系统已经不太现实&#xff0c;有没有更简单…

docker 搭建多个Linux系统环境 安装多个不同语言的项目

docker 搭建多个Linux系统环境 安装多个不同语言的项目 宝塔dockers可视化界面 https://blog.51cto.com/u_16213709/9473968

xss.pwnfunction-Jefff

在eval中可以直接执行命令所以直接把"直接闭合在结尾再加上一个"因为后面的"没闭和会报错 ?jeffa";alert(1);" 或 ?jeffa"-alert(1)-" -是分隔符

线段树和树状数组

实战演练 1.【模板】树状数【模板】树状数组1 输入&#xff1a; 5 5 1 5 4 2 3 2 2 4 1 2 3 2 2 3 4 1 1 5 1 2 1 4 注意&#xff1a;只修改一个数&#xff08;单点修改&#xff09;&#xff0c;却要输出一个区间的值&#xff08;区间查询&#xff09;&#xff01;&#xff…

SAP操作教程第14期:SAP B1如何进行自定义字段位置设置

服务对于企业而言永远是重中之重&#xff0c;想要提高服务呼叫效率&#xff0c;员工必须能够快速扫描单据和主数据中的重要信息&#xff0c;及时响应客户。那么&#xff0c;拥有适合企业业务流程的表单则是必不可少的前提。 所以&#xff0c;今天我们就来了解一下&#xff0c;在…

数据库连接查询

一、联合查询 1.使用 union 连接两个 select 语句进行联合查询 select 列 1&#xff0c;列 2... from 表名 where 条件 union select 列 1&#xff0c;列 2... from 表名 where 条 件; select vend_id,prod_id,prod_name,prod_price from products where prod_price < 5…

网络与通信Day1-路由协议

网络协议之路由协议 静态路由&#xff1a; 明细静态 默认静态 动态路由&#xff1a;&#xff08;可以自动去环&#xff09; RIP 十几台或几十台 &#xff08;维护上一代人搭建的网络&#xff09; OSPF 300台 &#xff08;最短路径算法&#xff09; ISIS 1200台 BGP…

[C++][算法基础]模拟堆(堆)

维护一个集合&#xff0c;初始时集合为空&#xff0c;支持如下几种操作&#xff1a; I x&#xff0c;插入一个数 x&#xff1b;PM&#xff0c;输出当前集合中的最小值&#xff1b;DM&#xff0c;删除当前集合中的最小值&#xff08;数据保证此时的最小值唯一&#xff09;&…

UE小:UE5.3无法创建C++工程

当您在使用Unreal Engine (UE) 构建项目时&#xff0c;如果遇到以下问题&#xff1a; Running C:/Program Files/Epic Games/UE\_5.3/Engine/Build/BatchFiles/Build.bat -projectfiles -project"C:/UEProject/Shp\_1/Shp\_1.uproject" -game -rocket -progress Usi…

python之正则表达式(2)

1、贪婪量词和懒惰量词 贪婪量词&#xff1a;也就是尽可能多的匹配字符 懒惰量词&#xff1a;尽可能少的匹配字符&#xff08;在现在的计算机语言中大多默认为贪婪量词若想要使用 懒惰量词就需要在后面加上&#xff1f;即可&#xff09; 代码示例&#xff1a; import rep …

JavaScript - 你遇到过哪几种Javascript的错误类型

难度级别:中级及以上 提问概率:50% 我们在开发Javascript代码的时候,经常一不小心就会遇到各种各样的异常,浏览器也会及时给出错误信息,那么一般会遇到哪几种异常情况呢,我们来看一下。 1 ReferenceError错误 ReferenceError几乎是最…

代码随想录训练营day29

第七章 回溯算法 part05 1.LeetCode. 递增子序列 1.1题目链接&#xff1a;491.递增子序列 文章讲解&#xff1a;代码随想录 视频讲解&#xff1a;B站卡哥视频 1.2思路&#xff1a;这个递增子序列比较像是取有序的子集。而且本题也要求不能有相同的递增子序列。这又是子集&a…

光伏EPC项目管理系统的综合性管理理念和功能优势。

光伏EPC项目管理系统是一种适用于工程项目的管理软件&#xff0c;它强调在整个项目周期中的综合性管理理念&#xff0c;涵盖了从规划、设计、采购、施工到交付等全过程&#xff0c;帮助用户实现高效的项目管理。 1.增强项目团队之间的协作与沟通&#xff1a;光伏EPC项目管理系统…