Description:

一个 m * n 的棋盘,有的格子存在障碍,求经过所有非障碍格子的哈密顿回路个数

Hint:

\(n,m<=12\)

Solution:

插头dp模板题,注意要讨论多种情况,详见代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mxn=15,c[4]={0,-1,1,0};
struct data {
int key; ll val;
};
int n,m,t,ex,ey;
char mp[mxn][mxn];
unordered_map<int ,data > dp[3];
typedef unordered_map<int ,data >::iterator uit; inline void copy(data x,int id) {dp[id][x.key<<2]=(data){x.key<<2,x.val};} //复制一遍 inline int get(int st,int x) {x<<=1; return (st>>x)&3;}
inline int md(int st,int x,int val) {x<<=1; return (st&(~(3<<x)))|(val<<x);} inline int getl(int st,int x) {
int l=x,cnt=1;
while(cnt!=0) cnt+=c[get(st,--l)];
return l;
} inline int getr(int st,int x) {
int r=x,cnt=-1;
while(cnt!=0) cnt+=c[get(st,++r)];
return r;
} inline void update(int x,int y,data d)
{
int st=d.key; ll val=d.val;
int p=get(st,y),q=get(st,y+1);
if(mp[x][y]=='*') {
if(p==0&&q==0) dp[t^1][st]=(data){st,dp[t^1][st].val+val};
return ;
}
if(p==0&&q==0) {
if(x==n-1||y==m-1) return ;
int nst=md(st,y,1); nst=md(nst,y+1,2);
dp[t^1][nst]=(data){nst,dp[t^1][nst].val+val};
return ; //不要少写return
}
if(p==0||q==0) {
if(y<m-1) {
int nst=md(st,y,0); nst=md(nst,y+1,p+q);
dp[t^1][nst]=(data){nst,dp[t^1][nst].val+val};
}
if(x<n-1) {
int nst=md(st,y,p+q); nst=md(nst,y+1,0);
dp[t^1][nst]=(data){nst,dp[t^1][nst].val+val};
}
return ;
}
int nst=md(st,y,0); nst=md(nst,y+1,0);
if(p==1&&q==1) nst=md(nst,getr(st,y+1),1);
if(p==2&&q==2) nst=md(nst,getl(st,y),2);
if(p==1&&q==2&&(x!=ex||y!=ey)) return ;
dp[t^1][nst]=(data){nst,dp[t^1][nst].val+val};
} int main()
{
scanf("%d%d",&n,&m);
for(int i=0;i<n;++i) scanf("%s",mp[i]);
for(int i=0;i<n;++i)
for(int j=0;j<m;++j)
if(mp[i][j]=='.') ex=i,ey=j;
t=0; dp[t][0]=(data){0,1ll};
for(int i=0;i<n;++i) {
dp[2].clear();
for(uit j=dp[t].begin();j!=dp[t].end();++j) copy((*j).second,2);
dp[t].clear();
for(uit j=dp[2].begin();j!=dp[2].end();++j) dp[t][(*j).second.key]=(*j).second; //这里由于map不支持直接修改键值,所以先全部拿出来,再处理
for(int j=0;j<m;++j) {
dp[t^1].clear();
for(uit k=dp[t].begin();k!=dp[t].end();++k)
update(i,j,(*k).second);
t^=1;
}
}
printf("%lld",dp[t][0].val);
return 0;
}

[BZOJ1814]Formula 1的更多相关文章

  1. 【BZOJ1814】Ural 1519 Formula 1 (插头dp)

    [BZOJ1814]Ural 1519 Formula 1 (插头dp) 题面 BZOJ Vjudge 题解 戳这里 上面那个链接里面写的非常好啦. 然后说几个点吧. 首先是关于为什么只需要考虑三进制 ...

  2. 【BZOJ1814】Ural 1519 Formula 1 插头DP

    [BZOJ1814]Ural 1519 Formula 1 题意:一个 m * n 的棋盘,有的格子存在障碍,求经过所有非障碍格子的哈密顿回路个数.(n,m<=12) 题解:插头DP板子题,刷板 ...

  3. bzoj1814 Ural 1519 Formula 1(插头dp模板题)

    1814: Ural 1519 Formula 1 Time Limit: 1 Sec  Memory Limit: 64 MBSubmit: 924  Solved: 351[Submit][Sta ...

  4. BZOJ1814: Ural 1519 Formula 1(插头Dp)

    Description Regardless of the fact, that Vologda could not get rights to hold the Winter Olympic gam ...

  5. bzoj1814 Ural 1519 Formula 1(插头DP)

    对插头DP的理解还不是很透彻. 先说一下肤浅的理解吧. 插头DP使用范围:指数级复杂度,且适用于解决网格图连通性问题,如哈密顿回路等问题.插头一般指每相邻2个网格的接口. 题目难度:一般不可做. 使用 ...

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

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

  7. 插头DP讲解+[BZOJ1814]:Ural 1519 Formula 1(插头DP)

    1.什么是插头$DP$? 插头$DP$是$CDQ$大佬在$2008$年的论文中提出的,是基于状压$D$P的一种更高级的$DP$多用于处理联通问题(路径问题,简单回路问题,多回路问题,广义回路问题,生成 ...

  8. redmine computed custom field formula tips

    项目中要用到Computed custom field插件,公式不知道怎么写,查了些资料,记录在这里. 1.http://apidock.com/ruby/Time/strftime 查看ruby的字 ...

  9. salesforce 零基础开发入门学习(十五)salesforce中formula的使用(不含Date/Time)

    本文参考官方的formula介绍PDF:https://resources.docs.salesforce.com/200/latest/en-us/sfdc/pdf/salesforce_usefu ...

随机推荐

  1. python提取文件中的方法名称

    #提取文件中的方法名称 # -*- coding:utf-8 -*- def Query_Method(filepath): file = open(filepath,'r',encoding= 'U ...

  2. ORA-12705

    1. 分析 ORA-12705是一个与nls 环境或者文件相关的错误,按照Oracle 官方的提示,要么是环境变量配置错误,要么是通过alter session 命令调整了错误的nls参数值,要么是n ...

  3. last与lastb命令 读取的日志文件

    在linux系统中,last与lastb命令用来列出目前与过去登录系统的用户相关信息.指令英文原义: last, lastb - show listing of last logged in user ...

  4. python基础知识之zip

    names =['zhangning','lsl','lyq','xww']age = [1,2,3,4]for a,b in zip(names,age): print(a,b)S = 'abcde ...

  5. EntityFramework Reverse POCO Code First 反向生成器

    https://marketplace.visualstudio.com/items?itemName=SimonHughes.EntityFrameworkReversePOCOGenerator ...

  6. gitblit删除版本库

    Git客户端不提供删除远程仓库的方法,gitblit服务器网页也不支持删除版本仓库.若要强制删除,Windows下可以: 先在任务管理器中停止gitblit进程,然后将gitblit版本库文件夹中将版 ...

  7. Newtonsoft.Json WindowPhone7.1

    才发现最新版本的Newtonsoft.Json 已经不支持wp71了… 查了下最后一个支持的版本是Json.NET 5.0 Release 8… 安装的时候需要: Install-Package Ne ...

  8. java传值和传引用区别

    1. 在java中所有的参数都是传值的,引用符号&的传递是C++中才有的:2. 在java传参中,基本类型(byte--short--int--long--float--double--boo ...

  9. mongodb中投票节点作用

    投票节点 并不含有 复制集中的数据集副本,且也 无法 升职为主节点.投票节点的存在是为了使复制集中的节点数量为奇数,这样保证在进行投票的时候不会出现票数相同的情况.如果添加了一个节点后,总节点数为偶数 ...

  10. 使用sparkSQL的insert操作Kudu

    可以选择使用Spark SQL直接使用INSERT语句写入Kudu表:与'append'类似,INSERT语句实际上将默认使用UPSERT语义处理: import org.apache.kudu.sp ...