动态规划:插头DP
这种动归有很多名字,插头DP是最常见的
还有基于连通性的动态规划
轮廓线动态规划等等
超小数据范围,网格图,连通性
可能算是状态压缩DP的一种变式
以前我了解的状压DP用于NP难题的小数据范围求解
这里说一下哈密顿回路的概念:
哈密顿回路:
、指一个对图的每个顶点都只穿越一次的回路。也可以 定义为n+1个相邻顶点v0, v1, … ,vn, v0的一个序列,其中序列的第一个顶点和最后一个顶点是相同的,而其他n-1个顶点是互不相同的。
、当这个图是加权图时,求该图的最短哈密顿回路,就是传说中的旅行商问题(TSP)。
然后是一道插头DP的入门题
一个网格图中有若干障碍格子,求其他格子的哈密尔顿回路总数
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int LIM=,Has=;
int n,m,e1,e2,las,now,tt;LL ans;
int mp[][],bin[],tot[];LL js[][LIM];
int h[],a[][LIM],ne[LIM];
//tot:状态总数,js:该状态的方案总数,a:各种状态
void ins(int zt,LL num) {//卓越的哈希技术
int tmp=zt%Has+;
for(int i=h[tmp];i;i=ne[i])
if(a[now][i]==zt) {js[now][i]+=num;return;}
ne[++tot[now]]=h[tmp],h[tmp]=tot[now];
a[now][tot[now]]=zt,js[now][tot[now]]=num;
}
void work() {
tot[now]=,js[now][]=,a[now][]=;
for(int i=;i<=n;++i) {
for(int j=;j<=tot[now];++j) a[now][j]<<=;//切换行了
for(int j=;j<=m;++j) {
las=now,now^=;
memset(h,,sizeof(h)),tot[now]=;
for(int k=;k<=tot[las];++k) {
int zt=a[las][k],b1=(zt>>(j*-))%,b2=(zt>>(j*))%;//提取关键格子上的两段轮廓线状态
LL num=js[las][k];
if(!mp[i][j]) {if(!b1&&!b2) ins(zt,num);}
else if(!b1&&!b2)
{if(mp[i+][j]&&mp[i][j+]) ins(zt+bin[j-]+*bin[j],num);}
else if(!b1&&b2) {
if(mp[i][j+]) ins(zt,num);
if(mp[i+][j]) ins(zt-bin[j]*b2+bin[j-]*b2,num);
}
else if(b1&&!b2) {
if(mp[i][j+]) ins(zt-bin[j-]*b1+bin[j]*b1,num);
if(mp[i+][j]) ins(zt,num);
}
else if(b1==&&b2==) {
int kl=;
for(int t=j+;t<=m;++t) {
if((zt>>(t*))%==) ++kl;
if((zt>>(t*))%==) --kl;
if(!kl) {ins(zt-bin[j]-bin[j-]-bin[t],num);break;}
}
}
else if(b1==&&b2==) {
int kl=;
for(int t=j-;t>=;--t) {
if((zt>>(t*))%==) --kl;
if((zt>>(t*))%==) ++kl;
if(!kl) {ins(zt+bin[t]-*bin[j]-*bin[j-],num);break;}
}
}
else if(b1==&&b2==) ins(zt-*bin[j-]-bin[j],num);
else if(i==e1&&j==e2) ans+=num;
}
}
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=n;++i)
for(int j=;j<=m;++j) {
char ch=getchar();
while(ch!='*'&&ch!='.') ch=getchar();
if(ch=='.') mp[i][j]=,e1=i,e2=j;
}
bin[]=;for(int i=;i<=;++i) bin[i]=bin[i-]<<;
work(),printf("%lld\n",ans);
return ;
}
然后是HDU1693
给一个n*m的地图,有些格子是不可到达的,要把所有可到达的格子的树都吃完,并且要走回路,求方案数
允许有多个回路,找一条或多条回路,吃完所有的树
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
int n,m,T,kas,bin[],mp[][];LL f[][][(<<)];
int main()
{
scanf("%d",&T);
bin[]=;for(int i=;i<=;++i) bin[i]=bin[i-]<<;
while(T--) {
scanf("%d%d",&n,&m);
for(int i=;i<=n;++i)
for(int j=;j<=m;++j) scanf("%d",&mp[i][j]);
memset(f,,sizeof(f));
f[][m][]=;int lim=bin[m+]-;
for(int i=;i<=n;++i) {
for(int zt=;zt<=lim;++zt) f[i][][zt<<]=f[i-][m][zt];
for(int j=;j<=m;++j)
for(int zt=;zt<=lim;++zt) {
int b1=zt&bin[j-],b2=zt&bin[j];LL num=f[i][j-][zt];
if(!mp[i][j]) {if(!b1&&!b2) f[i][j][zt]+=num;}
else if(!b1&&!b2)
{if(mp[i][j+]&&mp[i+][j])f[i][j][zt+bin[j-]+bin[j]]+=num;}
else if(!b1&&b2) {
if(mp[i][j+]) f[i][j][zt]+=num;
if(mp[i+][j]) f[i][j][zt-bin[j]+bin[j-]]+=num;
}
else if(b1&&!b2) {
if(mp[i][j+]) f[i][j][zt-bin[j-]+bin[j]]+=num;
if(mp[i+][j]) f[i][j][zt]+=num;
}
else f[i][j][zt-bin[j-]-bin[j]]+=num;
}
}
printf("Case %d: There are %lld ways to eat the trees.\n",++kas,f[n][m][]);
}
return ;
}
动态规划:插头DP的更多相关文章
- 51Nod1518 稳定多米诺覆盖 动态规划 插头dp 容斥原理
原文链接https://www.cnblogs.com/zhouzhendong/p/51Nod1518.html 题目传送门 - 51Nod1518 题意 51Nod真是个好OJ ,题意概括的真好, ...
- bzoj1814: Ural 1519 Formula 1 动态规划 插头dp
http://acm.timus.ru/problem.aspx?space=1&num=1519 题目描述 一个 m * n 的棋盘,有的格子存在障碍,求经过所有非障碍格子的哈密顿回路个数. ...
- 动态规划之插头DP入门
基于联通性的状态压缩动态规划是一类非常典型的状态压缩动态规划问题,由于其压缩的本质并不像是普通的状态压缩动态规划那样用0或者1来表示未使用.使用两种状态,而是使用数字来表示类似插头的状态,因此.它又被 ...
- 插头DP(基于连通性状态压缩的动态规划问题)(让你从入门到绝望)
今天,我,Monkey king 又为大家带来大(ju)佬(ruo)的算法啦!--插头DP 例题(菜OJ上的网址:http://caioj.cn/problem.php?id=1489): 那么,这道 ...
- Luogu P3170 [CQOI2015]标识设计 状态压缩,轮廓线,插头DP,动态规划
看到题目显然是插头\(dp\),但是\(n\)和\(m\)的范围似乎不是很小.我们先不考虑复杂度设一下状态试试: 一共有三个连通分量,我们按照\(1,2,3\)的顺序来表示一下.轮廓线上\(0\)代表 ...
- Luogu P3886 [JLOI2009]神秘的生物 最小表示法,轮廓线DP,插头DP,动态规划
亲手写掉的第一道最小表示法!哈哈哈太开心啦~ 不同于以往的几个插头\(dp\),这个题目的轮廓线是周围的一圈\(n\)个格子.而其所谓"插头"也变成了相邻格子的所属连通分量编号,并 ...
- 插头DP专题
建议入门的人先看cd琦的<基于连通性状态压缩的动态规划问题>.事半功倍. 插头DP其实是比较久以前听说的一个东西,当初是水了几道水题,最近打算温习一下,顺便看下能否入门之类. 插头DP建议 ...
- 动态规划——数位dp
通过先前在<动态规划——背包问题>中关于动态规划的初探,我们其实可以看到,动态规划其实不是像凸包.扩展欧几里得等是具体的算法,而是一种在解决问题中决策的思想.在不同的题目中,我们都需要根据 ...
- 初探 插头DP
因为这题,气得我火冒三丈! 这数据是不是有问题啊!我用cin代替scanf后居然就AC了(本来一直卡在Test 18)!导致我调(对)试(排)了一个小时!! UPD:后来细细想想,会不会是因为scan ...
随机推荐
- 欢迎来怼—第二次Scrum会议
一.小组信息 队名:欢迎来怼小组成员队长:田继平成员:李圆圆,葛美义,王伟东,姜珊,邵朔,冉华小组照片 二.开会信息 时间:2017/10/14 18:30~18:47,总计17min.地点:东北师范 ...
- bash循环语句
1 )单分支if语句 if 测试条件 :then 如果满足条件就执行这里的代码 f 2)双分支的if语句 if 测试条件:then 如果满足条件就执行这里的代码 else 如果不满足条件就执行这里 ...
- openssl 加密算法 CA 介绍
首先对于tftp服务的简要使用说明 (1)yum安装:tftp.tftp-server (2)启动tftp CentOS 6 service xinetd restart chkconfig tf ...
- NFS 它的目的就是想让不同的机器、不同的作业系统可以彼此分享个别的档案啦
NFS即网络文件系统,是FreeBSD支持的文件系统中的一种,它允许网络中的计算机之间通过TCP/IP网络共享资源.在NFS的应用中,本地NFS的客户端应用可以透明地读写位于远端NFS服务器上的文件, ...
- 【BioCode】删除未算出PSSM与SS的蛋白质序列
代码说明: 由于一些原因(氨基酸序列过长),没有算出PSSM与SS,按照整理出来的未算出特征的文件,删除原来的蛋白质序列: 需删除的氨基酸文件732.txt(共732条氨基酸): 删除前 氨基酸共25 ...
- 解决java图形界面label中文乱码
第一:在你的具有main函数的类也即你应用运行的主类上点击右键,选择Run As中的Run Configurations,如下图:java,awt,中文方框,中文乱码第二,在Arguments标签下的 ...
- Linux下objdump查看C程序编译后的汇编代码
http://m.blog.csdn.net/article/details?id=47747047 Uboot中start.S源码的指令级的详尽解析 http://www.crifan.com/fi ...
- Hibernate 应知应会
Hibernate 的关联关系的配置: 一对一外键约束: 举例子是一个丈夫和妻子:[一个丈夫只能有一位妻子] 表结构: CREATE TABLE `tbl_hus` ( `uuid` ) NOT NU ...
- 【Python】Python对象类型及其运算
Python对象类型及其运算 基本要点: 程序中储存的所有数据都是对象(可变对象:值可以修改 不可变对象:值不可修改) 每个对象都有一个身份.一个类型.一个值 例: >>> a1 = ...
- 802.1p 优先级与内部优先级的映射关系
缺省情况下,所有华为 S 系列交换机的 802.1P 优先级 与内部优先级的映射关系是 一 样的,如表 10-3 所示.从中可以看出,这些交换机中 802.1p 优先级与内部优先级的缺省映射关系是按等 ...