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. WPF下Itemscontrol分组 样式

    原文 WPF下Itemscontrol分组 样式 <ItemsControl Grid.Row="1" DataContext="{Binding Layouts} ...

  2. PHP XDebug Sublime Text 单步调试

    前置环境:已经安装好LNMP 1. 安装xdebug 可以通过pear包管理来安装 sudo apt-get install php-pear sudo pecl install xdebug 这里我 ...

  3. 使用Newtonsoft.Json输出JSON

    安装: Install-Package Newtonsoft.Json 代码: //序列化DataTable DataTable dt = new DataTable(); dt.Columns.Ad ...

  4. Windows 10 版本信息

    原文 https://technet.microsoft.com/zh-cn/windows/release-info Windows 10 版本信息 Microsoft 已更新其服务模型. 半年频道 ...

  5. 在Visual Studio2015中使用单元测试

    所谓的单元测试(Unit Test),就是对软件的一些模块进行测试以检查其正确性和可靠性,这些模块可以是一个类或者是一个方法等.在Visual studio中,这十分容易实现. 打开Visual st ...

  6. 教你如何快速使用Github

    以前看过几篇github的使用教程,感觉还是不是很清晰,自从看到了这篇,通俗易懂,也学会基本的使用了,在此为大家推荐.(转自知乎,为了能让更多的人看到,请允许我使用 “原创”,如果侵权请联系.) Gi ...

  7. 重写QLineEdit,实现编辑框内添加删除按钮的功能(随时把控件Move到一个地方,然后show就可以了,这是万能的办法)

    http://www.qtcn.org/bbs/read-htm-tid-62265-ds-1-page-1.html#180286

  8. LockWindowUpdate

     //锁住listview防止反复刷新              LockWindowUpdate(Self.lvsearch.Handle);    貌似不太行,多用几下就卡住了  那个函数几乎不用 ...

  9. Waveform基于JavaScript的开源多声道音乐波形编辑器

    快速使用Romanysoft LAB的技术实现 HTML 开发Mac OS App,并销售到苹果应用商店中.   <HTML开发Mac OS App 视频教程> 土豆网同步更新:http: ...

  10. 为什么你有10年经验,但成不了专家?(重复性刻意训练+反馈修正,练习的精髓是要持续地做自己做不好的,太精彩了)真正的高手都有很强的自学能力,老师和教练的最重要作用是提供即时的反馈(莫非我从小到大学习不好的原因在这里?没有单独刻意训练?) good

    也许简单看书就是没有刻意训练.更没有反馈,所以没有效果 我倒是想起自己,研究VCL源码的时候,都是自己给自己提问,然后苦思冥想.自己解决问题,然后Windows编程水平果然上了一个台阶.对什么叫做“框 ...