bzoj3125: CITY 题解
3125: CITY
Time Limit: 10 Sec Memory Limit: 128 MB
Submit: 486 Solved: 213
[Submit][Status][Discuss]
Description
Input
Output
Sample Input
2 2
..
..
Sample 2
Input:
4 4
....
..-.
....
....
Sample Output
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 题解的更多相关文章
- ZOJ 3195 Design the city 题解
这个题目大意是: 有N个城市,编号为0~N-1,给定N-1条无向带权边,Q个询问,每个询问求三个城市连起来的最小权值. 多组数据 每组数据 1 < N < 50000 1 < Q ...
- 2019.01.24 bzoj3125: CITY(轮廓线dp)
传送门 题意简述:给一个n∗mn*mn∗m的网格图,有的格子不能走,有的格子只能竖着走,有的格子只能横着走,问用一条回路覆盖所有能走的格子的方案数. 思路: 就是简单的轮廓线dpdpdp加了一点限制而 ...
- caioj1497&&bzoj3125: CITY
震惊!bzoj居然又被苏大佬D飞了... 这题煞笔模板题好吧. 然而bzojAC caiojWA%40??? 好强啊 今天早上发现是m打成n了囧 #include<cstdio> #inc ...
- CodeForces 821D Okabe and City
Okabe and City 题解: 将行和列也视为一个点. 然后从普通的点走到行/列的点的话,就代表这行/列已经被点亮了. 然后将费用为0的点建上边. 注意讨论(n,m)非亮的情况下. 代码: #i ...
- cf公式专场-续
Benches Time Limit:500MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u Submit Statu ...
- 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 ...
- 插头dp题表
bzoj1814: Ural 1519 Formula 1 bzoj3125: CITY bzoj1210: [HNOI2004]邮递员 bzoj2331: [SCOI2011]地板 bzoj1187 ...
- Codeforces Round #678 (Div. 2)【ABCD】
比赛链接:https://codeforces.com/contest/1436 A. Reorder 题解 模拟一下这个二重循环发现每个位置数最终都只加了一次. 代码 #include <bi ...
- 【bzoj3125】CITY 插头dp
题目描述 给出一个n*m的矩阵,某些格子不能通过,某些格子只能上下通过或左右通过.求经过所有非不能通过格子的哈密顿回路条数. 输入 第一行有两个数N, M表示地图被分割成N*M个块,接下来有N行,每行 ...
随机推荐
- CenOS7 docker部署lnmp环境
Step1:下载lnmp镜像 [root@docker html]# docker pull winstonpro/lnmp Step2:启动lnmp镜像的docker实例 [root@docker ...
- ArcGIS中Python逆地理编码,根据坐标获取实际的地址
import json import urllib import arcpy def getAddress(lng,lat): url= 'http://restapi.amap.com/v3/geo ...
- Linux C/C++编程手册查阅方法
Linux Programmer's Manual & User Commands https://www.kernel.org/doc/man-pages/ 搜索框输入epoll调用搜索引擎 ...
- OpenGL与Directx的区别
OpenGL 只是图形函数库. DirectX 包含图形, 声音, 输入, 网络等模块. 单就图形而论, DirectX 的图形库性能不如 OpenGL OpenGL稳定,可跨平台使用.但 OpenG ...
- 开源代码分析工具 good
checkstyle - static code analysis tool for JavaPMD - A source code analyzer
- Qt设置窗体的透明度: setWindowOpacity
在Qt中,设置窗体透明度的函数有:void setWindowOpacity(qreal level) 特性: 透明度的有效范围从1.0(完全不透明)到0.0(完全透明的). 默认情况下,此属 ...
- 监控打印机(使用OpenPrinter,WaitForPrinterChange API函数)
uses Winapi.WinSpool; procedure TForm1.Button1Click(Sender: TObject);varpi2: PRINTER_INFO_2;hPrinter ...
- 35+个实用jQuery菜单插件
应用jQuery菜单插件可以让浏览者在浏览你的网页时获得最好的动态导航.jQuery是一个轻量级.跨浏览器的JavaScript框架(库),效果非常给力,它强调并简化了JavaScript.CSS和H ...
- git初学【常用命令、上传项目到码云或从码云拉取、克隆项目】
1.下载git.https://git-scm.com/ 注册码云:https://gitee.com/2.安装git: 默认安装即可: 安装完成之后打开git bash进行最后一步配置 输 ...
- 04 body中的相关标签
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...