题意:有一个n*m矩阵,其中有些格子必走,有些格子不可走,其他格子是可走也可不走,问有多少条哈密顿回路?

思路:

  本来是一道很简单的题,代码写多了连白痴bug都查不出了,竟然用i>=ex&&j>=ey来判定最后一个必走点后面的点!明显是错的。

  其实主要在选走的格子,那么有两种选择,“走”or“不走”,不走的话上一个格子的状态照搬过来。这样就没有了固定的终点了,因为终点可以是很多种情况(比如是选走点/必走点),那么只要是在ex和ey后面的格子(指的是(ex,ey)之后遍历的所有非障碍格子),都是可以作为终点的,只有在这些格子才可以将左右括号连起来(只统计但不插入)。其他的基本和常规的一样了,本次仍然用括号表示法,再过滤掉很多无效的状态,所以代码略长,但容易看。

 //#include <bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <cstring>
#define pii pair<int,int>
#define INF 0x3f3f3f3f
#define LL long long
using namespace std;
const int N=;
const int mod=;
const int NN=;
char g[N][N];
LL ans;
int cur, n, m, ex, ey, tx, ty;
struct Hash_Map
{
int head[mod]; //桶指针
int next[NN]; //记录链的信息
LL status[NN]; //状态
LL value[NN]; //状态对应的DP值。
int size; void clear() //清除哈希表中的状态
{
memset(head, -, sizeof(head));
size = ;
} void insert(LL st, LL val) //插入状态st的值为val
{
int h = st%mod;
for(int i=head[h]; ~i; i=next[i])
if(status[i] == st) //这个状态已经存在,累加进去。
{
value[i] += val;
return ;
}
status[size]= st; //找不到状态st,则插入st。
value[size] = val;
next[size] = head[h] ; //新插入的元素在队头
head[h] = size++;
}
}hashmap[]; inline int getbit(LL s,int pos) //取出状态s的第pos个插头
{
return (s>>*pos)&;
}
inline int setbit(LL s,int pos,int bit) //将状态s的第pos个插头设置为bit
{
if(s&(<<*pos )) s^=<<(*pos);
if(s&(<<(*pos+))) s^=<<(*pos+);
return (s|(bit<<*pos));
} int Fr(LL s,int pos,int bit) //寻找状态s的第pos个插头对应的右括号。
{
int cnt=;
for(pos+=; pos<m; pos++)
{
if(getbit(s, pos)==-bit) cnt++;
if(getbit(s, pos)==bit) cnt--;
if(cnt==-) return setbit(s, pos, -bit);
}
}
int Fl(LL s,int pos,int bit) //寻找状态s的第pos个插头对应的左括号。
{
int cnt=;
for(pos--; pos>=; pos--)
{
if(getbit(s, pos)==-bit) cnt++;
if(getbit(s, pos)==bit) cnt--;
if( cnt==-) return setbit(s, pos, -bit);
}
} void DP(int i,int j) //非障碍空格
{
LL t;
for(int k=; k<hashmap[cur^].size; k++)
{
LL s=hashmap[cur^].status[k];
LL v=hashmap[cur^].value[k];
int R=getbit(s,j), D=getbit(s,j+);
if(g[i][j]=='X') //障碍格子
{
if( R== && D== ) hashmap[cur].insert(s, v);
continue ;
}
if(R && D) //两个括号
{
t=(setbit(s,j,)&setbit(s,j+,));
if(R==D) //同个方向的括号
{
if(R==) t=Fr(t, j, ); //要改
else t=Fl(t, j, );
hashmap[cur].insert(t, v);
}
else if( R== && D== ) //不同的连通分量
hashmap[cur].insert(t, v);
else if(t== && ( i>ex || (i==ex && j>=ey))) //注意点!
ans+=v;
}
else if(R || D) //仅1个括号
{
if(R)
{
if(i+<n && g[i+][j]!='X') hashmap[cur].insert(s, v);
if(j+<m && g[i][j+]!='x') hashmap[cur].insert(setbit(setbit(s,j,), j+, R), v);
}
else
{
if(j+<m && g[i][j+]!='X') hashmap[cur].insert(s, v);
if(i+<n && g[i+][j]!='X') hashmap[cur].insert(setbit(setbit(s,j+,), j, D), v);
}
}
else //无括号
{
if( g[i][j+]!='X' && g[i+][j]!='X' && j+<m && i+<n ) //新括号
hashmap[cur].insert( setbit(s,j,)|setbit(s,j+,), v);
if( g[i][j]=='*' ) //此点可不走
hashmap[cur].insert( s, v);
}
}
} void cal()
{
for(int i=; i<n; i++)
{
cur^=;
hashmap[cur].clear();
for(int j=; j<hashmap[cur^].size; j++) //新行,需要左移一下状态。
hashmap[cur].insert( hashmap[cur^].status[j]<<, hashmap[cur^].value[j] );
for(int j=; j<m; j++)
{
cur^=;
hashmap[cur].clear();
DP(i,j);
if(i==tx && j==ty) return ; //最后的有效点
}
}
} int main()
{
//freopen("input.txt", "r", stdin);
int t, Case=;
cin>>t;
while(t--)
{
tx=ty=ex=ey=-;
ans=cur=;
memset(g, 'X', sizeof(g));
scanf("%d%d",&n,&m);
for(int i=; i<n; i++) //输入矩阵
{
for(int j=; j<m; j++)
{
char c=getchar();
if(c=='X'||c=='*'||c=='O')
{
g[i][j]=c;
if( c=='O' ) ex=i,ey=j; //必走格
if( c!='X' ) tx=i,ty=j; //终点格
}
else j--;
}
} hashmap[cur].clear();
hashmap[cur].insert(, ); //初始状态
cal();
cout<<"Case "<<++Case<<": "<<ans<<endl;
}
return ;
}

AC代码

FZU 1977 Pandora adventure (插头DP,常规)的更多相关文章

  1. FZU1977 Pandora adventure —— 插头DP

    题目链接:https://vjudge.net/problem/FZU-1977  Problem 1977 Pandora adventure Accept: 597    Submit: 2199 ...

  2. FZU 1977 Pandora adventure (DP)

    题意:给定一个图,X表示不能走,O表示必须要走,*表示可走可不走,问你多少种走的法,使得形成一个回路. 析: 代码如下: #pragma comment(linker, "/STACK:10 ...

  3. 【FZU】1977 Pandora adventure

    http://acm.fzu.edu.cn/problem.php?pid=1977 题意:n×m的网格,有3种格子,'O'必须经过.'*'可以选择经过.'X'不能经过.现在要求路径经过所有'O'且是 ...

  4. HDU 3377 Plan (插头DP,变形)

    题意:有一个n*m的矩阵,每个格子中有一个值(可能负值),要从左上角走到右下角,求路径的最大花费. 思路: 除了起点和终点外,其他的点可以走,也可以不走. (2)我用的是括号表示法,所以起始状态为') ...

  5. 插头DP专题

    建议入门的人先看cd琦的<基于连通性状态压缩的动态规划问题>.事半功倍. 插头DP其实是比较久以前听说的一个东西,当初是水了几道水题,最近打算温习一下,顺便看下能否入门之类. 插头DP建议 ...

  6. 插头dp练习

    最近学了插头dp,准备陆续更新插头dp类练习. 学习论文还是cdq那篇<基于连通性状态压缩的动态规划问题>. 基本的想法都讲得很通透了,接下来就靠自己yy了. 还有感谢kuangbin大大 ...

  7. URAL 1519 Formula 1 (插头DP,常规)

    题意:给一个n*m的矩阵,格子中是'*'则是障碍格子,不允许进入,其他格子都是必走的格子,所走格子形成一条哈密顿回路,问有多少种走法? 思路: 本来是很基础的题,顿时不知道进入了哪个坑.这篇插头DP的 ...

  8. 插头dp

    插头dp 感受: 我觉得重点是理解,算法并不是直接想出怎样由一种方案变成另一种方案.而是方案本来就在那里,我们只是枚举状态统计了答案. 看看cdq的讲义什么的,一开始可能觉得状态很多,但其实灰常简单 ...

  9. HDU 4113 Construct the Great Wall(插头dp)

    好久没做插头dp的样子,一开始以为这题是插头,状压,插头,状压,插头,状压,插头,状压,无限对又错. 昨天看到的这题. 百度之后发现没有人发题解,hust也没,hdu也没discuss...在acm- ...

随机推荐

  1. 二、Chrome开发者工具详解(2)-Network面板

    摘自: http://www.cnblogs.com/charliechu/p/5981346.html

  2. TypeScript完全解读(26课时)_3.TypeScript完全解读-Symbol

    ts中symbol的支持是按照es6的标准来的,只要我们学会es6中的symbol,就可以直接在ts中使用了 创建symbol 在example文件夹下新建symbol.ts 然后在根目录的index ...

  3. python3 封装之property 多态 绑定方法classmethod 与 非绑定方法 staticmethod

    property 特性 什么是特性property property 是一种特殊的属性,访问它时会执行一段功能(函数),然后返回值 例如 BMI指数(bmi是计算而来的,但很明显它听起来像是一个属性而 ...

  4. Angular6在自定义指令中使用@HostBingDing() 和@HostListener()

    emmm,,,最近在为项目的第二阶段铺路,偶然看到directive,想想看因为项目已经高度集成了第三方组件,所以对于自定义指令方面的经验自己实在知之甚少,后面经过阅读相关资料,总结一篇关于在自定义指 ...

  5. STLstack,queue

    今天一开始用C去摸栈和队列,差不多昨天早上也在摸,摸烦了就去搞DP然后DP也没搞好,就是很烦很烦!!!! 然后今天那些C的栈队列的步骤和名称熟的不要不要的,然而数据结构的c语言用指针,传递,简直麻烦, ...

  6. Matplotlib 如何显示中文

    Python 3.x 主要是如下代码 import os font = FontProperties(fname=os.path.expandvars(r"%windir%\fonts\si ...

  7. 【IDEA】关于 IDEA 中新建 web 项目的 webapp 文件夹没有小蓝点 ,启动服务,访问不到解决方案

    问题描述: 新建的 maven 的 Module 项目,webapp 文件夹也是在创建完项目后手动添加的,出现了 webapp 文件夹不能被识别的情况. 解决方案: 第一步:  选中项目按 F4 键, ...

  8. 黑马方法引用学习 Stream流 函数式接口 Lambda表达式 方法引用

  9. 黑马MySQL数据库学习day02 表数据CRUD 约束CRUD

    /* 基础查询练习: 1.字段列表查询 当查询全部字段时,一种简便方式,使用*代替全部字段(企业中不推荐使用) 2.去除重复行 DISTINCT,注意修饰的是行,也就是整个字段列表,而不是单个字段. ...

  10. Access restriction: The type 'JPEGCodec' is not API

    问题 今天导入项目时Eclipse报错如下: Access restriction: The type 'JPEGCodec' is not API (restriction on required ...