bzoj1814 Ural 1519 Formula 1(插头dp模板题)
1814: Ural 1519 Formula 1
Time Limit: 1 Sec Memory Limit: 64 MB
Submit: 924 Solved: 351
[Submit][Status][Discuss]
Description
Input
Output
Sample Input
**..
....
....
....
Sample Output
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm> using namespace std;
typedef long long ll; const int maxn = ;
const int pow[] = {,,,,,,,,,,,,};
int n,m,now,pre,tx,ty;
char map[][]; struct node
{
int head[maxn],nextt[maxn],tot;
ll sum[maxn],sta[maxn];
void clear()
{
memset(head,-,sizeof(head));
tot = ;
}
void push(ll x,ll v)
{
ll hashh = x % maxn;
for (int i = head[hashh]; i >= ; i = nextt[i])
{
if (sta[i] == x)
{
sum[i] += v;
return;
}
}
sta[tot] = x;
sum[tot] = v;
nextt[tot] = head[hashh];
head[hashh] = tot++;
}
} f[]; int turnleft(ll x,int k)
{
return x << pow[k];
} int get(ll x,int k)
{
return (x >> pow[k]) & ;
} ll del(ll x,int i,int j)
{
return x & (~( << pow[i])) & (~( << pow[j]));
} int findr(ll x,int pos)
{
int cnt = ;
for (int i = pos + ; i <= m; i++)
{
int k = get(x,i);
if (k == )
cnt++;
else if (k == )
cnt--;
if (!cnt)
return i;
}
} int findl(ll x,int pos)
{
int cnt = ;
for (int i = pos - ; i >= ; i--)
{
int k = get(x,i);
if (k == )
cnt++;
else if (k == )
cnt--;
if (!cnt)
return i;
}
} void solve2(int x,int y,int k)
{
int p = get(f[pre].sta[k],y - ); //右插头
int q = get(f[pre].sta[k],y); //下插头
ll staa = del(f[pre].sta[k],y - ,y); //将这两个插头删掉以后的状态
ll v = f[pre].sum[k];
if (!p && !q) //新建一个连通分量
{
if (map[x][y] == '*')
{
f[now].push(staa,v);
return;
}
if (x < n && y < n && map[x + ][y] == '.' && map[x][y + ] == '.')
f[now].push(staa | turnleft(,y - ) | turnleft(,y),v);
}
else if (!p || !q) //保持原来的连通分量
{
int temp = p + q;
if (x < n && map[x + ][y] == '.')
f[now].push(staa | turnleft(temp,y - ),v);
if (y < m && map[x][y + ] == '.')
f[now].push(staa | turnleft(temp,y),v);
}
else if (p == && q == ) //连接两个联通分量
f[now].push(staa ^ turnleft(,findr(staa,y)),v); //这里的异或实际上就是把1变成2,2变成1
else if (p == && q == )
f[now].push(staa ^ turnleft(,findl(staa,y - )),v);
else if (p == && q == )
f[now].push(staa,v);
else if (x == tx && y == ty)
f[now].push(staa,v);
} ll solve()
{
f[].clear();
f[].push(,);
now = ,pre = ; //滚动数组
for (int i = ; i <= n; i++)
{
pre = now;
now ^= ;
f[now].clear();
for (int k = ; k < f[pre].tot; k++)
f[now].push(turnleft(f[pre].sta[k],),f[pre].sum[k]); //左移一位,因为轮廓线下来的时候会少一个插头
for (int j = ; j <= m; j++)
{
pre = now;
now ^= ;
f[now].clear();
for (int k = ; k < f[pre].tot; k++)
solve2(i,j,k); //处理第k个状态
}
}
for (int i = ; i < f[now].tot; i++)
if (f[now].sta[i] == ) //没有插头了.
return f[now].sum[i];
return ;
} int main()
{
scanf("%d%d",&n,&m);
for(int i = ; i <= n; i++)
scanf("%s",map[i] + );
for (int i = ; i <= n; i++)
for (int j = ; j <= m; j++)
if (map[i][j] == '.')
tx = i,ty = j; //找右下角的非障碍点
if (!tx)
puts("");
else
printf("%lld\n",solve()); return ;
}
bzoj1814 Ural 1519 Formula 1(插头dp模板题)的更多相关文章
- BZOJ1814: Ural 1519 Formula 1(插头Dp)
Description Regardless of the fact, that Vologda could not get rights to hold the Winter Olympic gam ...
- bzoj 1814: Ural 1519 Formula 1 插头dp经典题
用的括号序列,听说比较快. 然并不会预处理,只会每回暴力找匹配的括号. #include<iostream> #include<cstdio> #include<cstr ...
- 【BZOJ1814】Ural 1519 Formula 1 插头DP
[BZOJ1814]Ural 1519 Formula 1 题意:一个 m * n 的棋盘,有的格子存在障碍,求经过所有非障碍格子的哈密顿回路个数.(n,m<=12) 题解:插头DP板子题,刷板 ...
- bzoj 1814 Ural 1519 Formula 1 插头DP
1814: Ural 1519 Formula 1 Time Limit: 1 Sec Memory Limit: 64 MBSubmit: 942 Solved: 356[Submit][Sta ...
- Ural 1519 Formula 1 插头DP
这是一道经典的插头DP单回路模板题. 用最小表示法来记录连通性,由于二进制的速度,考虑使用8进制. 1.当同时存在左.上插头的时候,需要判断两插头所在连通块是否相同,若相同,只能在最后一个非障碍点相连 ...
- bzoj 1814 Ural 1519 Formula 1 ——插头DP
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1814 普通的插头 DP .但是调了很久.注意如果合并两个 1 的话,不是 “把向右第一个 2 ...
- 插头DP讲解+[BZOJ1814]:Ural 1519 Formula 1(插头DP)
1.什么是插头$DP$? 插头$DP$是$CDQ$大佬在$2008$年的论文中提出的,是基于状压$D$P的一种更高级的$DP$多用于处理联通问题(路径问题,简单回路问题,多回路问题,广义回路问题,生成 ...
- bzoj1814 Ural 1519 Formula 1(插头DP)
对插头DP的理解还不是很透彻. 先说一下肤浅的理解吧. 插头DP使用范围:指数级复杂度,且适用于解决网格图连通性问题,如哈密顿回路等问题.插头一般指每相邻2个网格的接口. 题目难度:一般不可做. 使用 ...
- 【Ural】1519. Formula 1 插头DP
[题目]1519. Formula 1 [题意]给定n*m个方格图,有一些障碍格,求非障碍格的哈密顿回路数量.n,m<=12. [算法]插头DP [题解]<基于连通性状态压缩的动态规划问题 ...
随机推荐
- 幸运三角形 南阳acm491(dfs)
幸运三角形 时间限制:1000 ms | 内存限制:65535 KB 难度:3 描述 话说有这么一个图形,只有两种符号组成(‘+’或者‘-’),图形的最上层有n个符号,往下个数依次减一,形成倒 ...
- (数据科学学习手札15)DBSCAN密度聚类法原理简介&Python与R的实现
DBSCAN算法是一种很典型的密度聚类法,它与K-means等只能对凸样本集进行聚类的算法不同,它也可以处理非凸集. 关于DBSCAN算法的原理,笔者觉得下面这篇写的甚是清楚练达,推荐大家阅读: ht ...
- COURSES POJ1469(模板)
Description Consider a group of N students and P courses. Each student visits zero, one or more than ...
- java web项目使用ant编译将不同的功能代码打包成jar,进而分局点将项目打包成不同的tar.gz包进而部署
使用ant可以轻松的将一个项目分离代码,直接打包成不同需求的tar.gz包使用 1.build.properties (属性) version.num=1.0 #版本信息 2.build.xml (a ...
- git的关于测试的相关的内容
今天,我们来讲一下git的分支的一些内容,在以前的时候,我一直都以为,对于一个项目,这个时候,我们把这个项目叫做项目a项目,这个a项目有master,staging,以及我自己的分支xxx,当我想上测 ...
- vs13发布web程序 iis上
一.配置iis 1,找到控制面板--程序--启用或关闭Windows功能 2,从列表中选择Internet Infomation Services,并且把相应的功能条目勾选上,如果不清楚,可以全部选中 ...
- 管理员常用Windows PowerShell命令Top25
即使Windows PowerShell已经由来已久,但很多管理员并不愿意主动熟悉PowerShell cmdlet命令行.随着微软扩展了PowerShell的功能,管理员应该对其功能及使用烂熟于心. ...
- 标志寄存器PSW和汇编条件转移指令解释
标志寄存器PSW 标志寄存器PSW(程序状态字寄存器PSW) 标志寄存器PSW是一个16为的寄存器.它反映了CPU运算的状态特征并且存放某些控制标志.8086使用了16位中的9位,包括6个状态标志 ...
- IDEA的terminal设置成Linux的终端一样
方式一:通过在Windows上安装Linux命令行工具 前提:需要安装Linux终端的命令行工具,并且最好可以安装 Gow (一个Windows下模拟Linux命令行工具集合,它集成了 Liunx 环 ...
- 西门子S7-200 SMART在win10环境下,使用虚拟机进行网络通信问题一二
原来的笔记本光荣退休,新买了小米笔记本17150.有个项目需要使用西门子S7-200 SMART,结果碰到了很多悲催的事情,新系统下的各种问题. 先贴下计算机配置,如下: 阶段一:安装问题 (1)在w ...