这种动归有很多名字,插头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的更多相关文章

  1. 51Nod1518 稳定多米诺覆盖 动态规划 插头dp 容斥原理

    原文链接https://www.cnblogs.com/zhouzhendong/p/51Nod1518.html 题目传送门 - 51Nod1518 题意 51Nod真是个好OJ ,题意概括的真好, ...

  2. bzoj1814: Ural 1519 Formula 1 动态规划 插头dp

    http://acm.timus.ru/problem.aspx?space=1&num=1519 题目描述 一个 m * n 的棋盘,有的格子存在障碍,求经过所有非障碍格子的哈密顿回路个数. ...

  3. 动态规划之插头DP入门

    基于联通性的状态压缩动态规划是一类非常典型的状态压缩动态规划问题,由于其压缩的本质并不像是普通的状态压缩动态规划那样用0或者1来表示未使用.使用两种状态,而是使用数字来表示类似插头的状态,因此.它又被 ...

  4. 插头DP(基于连通性状态压缩的动态规划问题)(让你从入门到绝望)

    今天,我,Monkey king 又为大家带来大(ju)佬(ruo)的算法啦!--插头DP 例题(菜OJ上的网址:http://caioj.cn/problem.php?id=1489): 那么,这道 ...

  5. Luogu P3170 [CQOI2015]标识设计 状态压缩,轮廓线,插头DP,动态规划

    看到题目显然是插头\(dp\),但是\(n\)和\(m\)的范围似乎不是很小.我们先不考虑复杂度设一下状态试试: 一共有三个连通分量,我们按照\(1,2,3\)的顺序来表示一下.轮廓线上\(0\)代表 ...

  6. Luogu P3886 [JLOI2009]神秘的生物 最小表示法,轮廓线DP,插头DP,动态规划

    亲手写掉的第一道最小表示法!哈哈哈太开心啦~ 不同于以往的几个插头\(dp\),这个题目的轮廓线是周围的一圈\(n\)个格子.而其所谓"插头"也变成了相邻格子的所属连通分量编号,并 ...

  7. 插头DP专题

    建议入门的人先看cd琦的<基于连通性状态压缩的动态规划问题>.事半功倍. 插头DP其实是比较久以前听说的一个东西,当初是水了几道水题,最近打算温习一下,顺便看下能否入门之类. 插头DP建议 ...

  8. 动态规划——数位dp

    通过先前在<动态规划——背包问题>中关于动态规划的初探,我们其实可以看到,动态规划其实不是像凸包.扩展欧几里得等是具体的算法,而是一种在解决问题中决策的思想.在不同的题目中,我们都需要根据 ...

  9. 初探 插头DP

    因为这题,气得我火冒三丈! 这数据是不是有问题啊!我用cin代替scanf后居然就AC了(本来一直卡在Test 18)!导致我调(对)试(排)了一个小时!! UPD:后来细细想想,会不会是因为scan ...

随机推荐

  1. C++:this指针的简单理解

    一.什么是this指针 要想理解什么是this指针,首先必须理解在C++中是如何为类的对象分配内存空间的. #include<iostream> using namespace std; ...

  2. “我爱淘”第二冲刺阶段Scrum站立会议3

    完成任务: 完成了注册界面的设计,以及部分代码,但是还没有完成服务器端的添加功能. 计划任务: 将注册功能实现了它,可以对数据库进行添加,在客户端实现分类功能,通过学院的分类查看书籍. 遇到问题: 分 ...

  3. 基于DPDK的高效数据包捕获技术分析与应用

    被NFV的论文折磨了两天,今天上午看了两篇DPDK的综述. 传统的包捕获机制 1. BPF 两个组成部分:转发部分和过滤部分. 转发部分负责从链路层提取数据包并转发给过滤部分. 过滤部分根据过滤规则, ...

  4. web会员注册页面代码(4)

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  5. hibernate.cfg.xml案例

    一.概念. hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库.既然学习Hibernate那么第 ...

  6. 树形结构的数据库表Schema设计-基于左右值编码

    树形结构的数据库表Schema设计 程序设计过程中,我们常常用树形结构来表征某些数据的关联关系,如企业上下级部门.栏目结构.商品分类等等,通常而言,这些树状结构需要借助于数据库完 成持久化.然而目前的 ...

  7. excel copy cell & batch operation & checkbox

    excel copy cell & batch operation & checkbox excel 右下角,下拉/双击 (复制 cell) 注意: 不是选择列

  8. LDPC译码器的FPGA实现

    应用笔记 V0.0 2015/3/17 LDPC译码器的FPGA实现   概述   本文将介绍LDPC译码器的FPGA实现,译码器设计对应CCSDS131x1o1s文档中提到的适用于深空通信任务的LD ...

  9. 只要实现了annotation这个接口就是注解 同理:只要实现了某个接口就是该类型的实现类

    只要实现了annotation这个接口就是注解  同理:只要实现了某个接口就是该类型的实现类

  10. HUST1017-Exact Cover

    给出一个\(n\times m\)的01矩阵,每行最多有\(c\)个1,求一个精确覆盖,即选出一些行使得每列有有且仅有一个1.输出方案. 分析 被这个题坑到了啊!!第一次上HUSTOJ做题,不知道没有 ...