3125: CITY

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 486  Solved: 213
[Submit][Status][Discuss]

Description

小明和小华要参加NOI,踏上了去X市的火车。
小明望着窗外的田野,大楼,工厂缓缓后退,在思考着什么。
这时,对面的小华拿出手机对着他说:“看!我们在这个位置!”
小明望着手机上显示的地图,城市被接到分割成各个方块,而自己所在的点在慢慢移动。
他突然意识到自己甚至还没游历过这个自己所在的小城市,学校和家貌以及之间来回的道路似乎成了这个小城的唯一印象。
若我把它们全部走一圈,可能要仔细计划下吧……不,那么多方案,其实我应该早能做到了吧……小明在心里对自己说。
 

Input

第一行有两个数N, M表示地图被分割成N*M个块,接下来有N行,每行有M个字符。
 .  表示这个块可以通过
 - 表示这个块只可以左右通过
 | 表示这个块只可以上下通过
 # 表示这个块不能通过
(从每个块只能走到其上下左右相邻的四个块)
 

Output

一个数,表示小明把所以可以通过的块都经过且只经过一次并回到原地的方案数。
 

Sample Input

Sample 1
2 2
..
..

Sample 2
Input:
4 4
....
..-.
....
....

Sample Output

Output 1
1

Output 2
1

HINT

数据范围: 0 < N, M < 13 不保证答案在long 范围之内

Source

  联赛后第一次写题解……

  这道题可以说得上是插头DP裸题了,话说最早接触插头DP是在学基础状压的时候误打误撞看到了CDQ的论文,差点入坑,然而最后我还是得入一下。

  这道题比较特殊的就是‘-’ ‘|’这两个设定,但其实也很容易,我们只要在转移的时候进行特判,‘-’只能接左插头,‘|’只能接上插头。其余转移同理。但是要注意的是由于许多转移代码大体结构一样,可以直接复制粘贴,但是细节还是要去检查一下,我因为特判粘贴后位置改变却没发现调了两个小时。

 #include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define N 15
using namespace std;
int n,m,ma[N][N],zz,tot[];
char bb[N];
int xp[N],b[],dl[];
long long f[][],ans;
bool check(int x,int t,int sum)
{
if(sum<) return ;
if(x==m+)
return sum==;
if(b[t/xp[x]]==) return check(x+,t,sum+);
else if(b[t/xp[x]]==) return check(x+,t,sum-);
else return check(x+,t,sum);
}
int main()
{
int nn,mm;
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)
{
scanf("%s",bb+);
for(int j=;j<=m;j++)
{
if(bb[j]=='.') ma[i][j]=,nn=i,mm=j;
else if(bb[j]=='-') ma[i][j]=,nn=i,mm=j;
else if(bb[j]=='|') ma[i][j]=,nn=i,mm=j;
}
}
xp[]=;
for(int i=;i<=m+;i++) xp[i]=xp[i-]*;
for(int i=;i<xp[m+];i++) b[i]=i%;
for(int i=;i<xp[m+];i++)
{
if(check(,i,))
{
zz++;
tot[zz]=i;
dl[i]=zz;
}
}
int now=,la=;
f[][]=;
for(int i=;i<=n;i++)
{
for(int j=;j<=m;j++)
{
la^=,now^=;
memset(f[now],,sizeof(f[now]));
int p,q,x=xp[j-],y=xp[j],t;
for(int k=;k<=zz;k++)
{
p=b[tot[k]/x],q=b[tot[k]/y];
t=tot[k]-p*x-q*y;
if(ma[i][j])
{
if(!p&&!q)
{
if(ma[i][j]==&&dl[t+x+(y<<)]) f[now][dl[t+x+(y<<)]]+=f[la][k];
}
else if(!q)
{
if(ma[i][j]!=)
{
if(j!=m&&dl[t+(y<<(p-))]) f[now][dl[t+(y<<(p-))]]+=f[la][k];
if(i!=n&&ma[i][j]==&&dl[t+(x<<(p-))]) f[now][dl[t+(x<<(p-))]]+=f[la][k];
}
}
else if(!p)
{
if(ma[i][j]!=)
{
if(j!=m&&ma[i][j]==&&dl[t+(y<<(q-))]) f[now][dl[t+(y<<(q-))]]+=f[la][k];
if(i!=n&&dl[t+(x<<(q-))]) f[now][dl[t+(x<<(q-))]]+=f[la][k];
}
}
else if(p==&&q==)
{
if(!t&&i==nn&&j==mm) ans+=f[la][k];
}
else if(p==&&q==)
{
if(ma[i][j]==)
{
if(dl[t]) f[now][dl[t]]+=f[la][k];
}
}
else if(p==&&q==)
{
if(ma[i][j]==)
{
int u,tmp;
for(u=j+,tmp=;u<=m&&tmp>=;tmp+=(b[t/xp[u]]==)-(b[t/xp[u]]==),u++);
u--;
if(t-xp[u]<) continue;
if(dl[t-xp[u]]) f[now][dl[t-xp[u]]]+=f[la][k];
}
}
else if(p==&&q==)
{
if(ma[i][j]==)
{
int u,tmp;
for(u=j-,tmp=;u>&&tmp>=;tmp+=(b[t/xp[u]]==)-(b[t/xp[u]]==),u--);
u++;
if(dl[t+xp[u]]) f[now][dl[t+xp[u]]]+=f[la][k];
}
}
}
else
{
if(!p&&!q&&dl[t]) f[now][dl[t]]+=f[la][k];
}
}
}
for(int j=zz;j>=;j--)
{
if(b[tot[j]]==)
{
if(dl[tot[j]/]) f[now][j]=f[now][dl[tot[j]/]];
else f[now][j]=;
}
else f[now][j]=;
}
}
printf("%lld\n",ans);
return ;
}

bzoj3125: CITY 题解的更多相关文章

  1. ZOJ 3195 Design the city 题解

    这个题目大意是: 有N个城市,编号为0~N-1,给定N-1条无向带权边,Q个询问,每个询问求三个城市连起来的最小权值. 多组数据 每组数据  1 < N < 50000  1 < Q ...

  2. 2019.01.24 bzoj3125: CITY(轮廓线dp)

    传送门 题意简述:给一个n∗mn*mn∗m的网格图,有的格子不能走,有的格子只能竖着走,有的格子只能横着走,问用一条回路覆盖所有能走的格子的方案数. 思路: 就是简单的轮廓线dpdpdp加了一点限制而 ...

  3. caioj1497&&bzoj3125: CITY

    震惊!bzoj居然又被苏大佬D飞了... 这题煞笔模板题好吧. 然而bzojAC caiojWA%40??? 好强啊 今天早上发现是m打成n了囧 #include<cstdio> #inc ...

  4. CodeForces 821D Okabe and City

    Okabe and City 题解: 将行和列也视为一个点. 然后从普通的点走到行/列的点的话,就代表这行/列已经被点亮了. 然后将费用为0的点建上边. 注意讨论(n,m)非亮的情况下. 代码: #i ...

  5. cf公式专场-续

    Benches Time Limit:500MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Statu ...

  6. USACO 5.4 Canada Tour

    Canada Tour You have won a contest sponsored by an airline. The prize is a ticket to travel around C ...

  7. 插头dp题表

    bzoj1814: Ural 1519 Formula 1 bzoj3125: CITY bzoj1210: [HNOI2004]邮递员 bzoj2331: [SCOI2011]地板 bzoj1187 ...

  8. Codeforces Round #678 (Div. 2)【ABCD】

    比赛链接:https://codeforces.com/contest/1436 A. Reorder 题解 模拟一下这个二重循环发现每个位置数最终都只加了一次. 代码 #include <bi ...

  9. 【bzoj3125】CITY 插头dp

    题目描述 给出一个n*m的矩阵,某些格子不能通过,某些格子只能上下通过或左右通过.求经过所有非不能通过格子的哈密顿回路条数. 输入 第一行有两个数N, M表示地图被分割成N*M个块,接下来有N行,每行 ...

随机推荐

  1. Win8 Metro(C#)数字图像处理--2.57一维最大熵法图像二值化

    原文:Win8 Metro(C#)数字图像处理--2.57一维最大熵法图像二值化  [函数名称] 一维最大熵法图像二值化WriteableBitmap EntropymaxThSegment(Wr ...

  2. 求 1-2+3-4+5-6+7-8....M 的结果算法

    static void Main(string[] args) { /** * 算法题: * 求 1-2+3-4+5-6+7-8....M 的结果. * */ //存储运算结果. ; //记号. ; ...

  3. Windows 10预装应用太多?一个命令删除!

    Windows 10预装了很多应用软件,虽然有些其实也不难用,但是使用率可能比较低,很多人也不喜欢预装的东西,而且还占空间,那么这些预装的如何彻底清除呢? 其实微软是自带了命令可以执行这样的操作,用它 ...

  4. 获取函数的地址(三种方法,分别是@,Addr,MethodAddress)

    问题来源: http://www.cnblogs.com/del/archive/2008/07/30/1039045.html#1272783 在编译器看来, 重载函数根本就是完全不同的几个函数, ...

  5. 视频技术详解:RTMP H5 直播流技术解析

    本文聚焦 RTMP 协议的最精华的内容,接进行实际操作 Buffer 的练习和协议的学习. RTMP 是什么 RTMP 全称即是 Real-Time Messaging Protocol.顾名思义就是 ...

  6. Storm 学习之路(二)—— Storm核心概念详解

    一.Storm核心概念 1.1 Topologies(拓扑) 一个完整的Storm流处理程序被称为Storm topology(拓扑).它是一个是由Spouts 和Bolts通过Stream连接起来的 ...

  7. 【数据结构--二叉树】Java递归实现二叉树遍历

    参考链接:https://www.cnblogs.com/yaobolove/p/6213936.html 这有一棵树: 1.节点对象 package com.tree.mybinarytree; / ...

  8. Django生成PDF显示在网页上以及解决中文显示乱码的问题

    项目地址:https://github.com/PythonerKK/django-generate-pdf/tree/master 这个demo实现了通过用户输入自己的个人信息生成一份简历pdf,来 ...

  9. jQuery入门——实现列表的显示隐藏与实现轮播图

    列表的显示与隐藏 <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head& ...

  10. PATA 1009. Product of Polynomials (25)

    1009. Product of Polynomials (25) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yu ...