来学插头DP了= =

  GDKOI前觉得不会考数位DP,GDOI前觉得插头DP用不上。。

  结果令人伤感>_<

  这题并不用增加状态。。

  只要在形成环的时候,让形成环的位置在最后一个必走点之后,并且此时只有一个联通分量。

  因为必走点处肯定有插头。。所以只有一个联通分量就意味着所有必走点都连在一起了。

  选择经过的点就在转移的时候多一种方法。。。

学的是最小表示法。。又长又慢TAT。。跳错坑了= =

 #include<cstdio>
#include<iostream>
#include<cstring>
#define ull unsigned long long
using namespace std;
const int modd=,maxzt=;
struct zs{
struct hash{
ull too;int pre;
}e[maxzt];int tot,last[modd];
ull f[maxzt],zt[maxzt]; inline int get(ull v){
int i,x=v%modd;
for(i=last[x];i&&e[i].too!=v;i=e[i].pre);
if(i&&e[i].too==v)return i;
e[++tot].too=v,e[tot].pre=last[x],last[x]=tot;
zt[tot]=v;f[tot]=;
return tot;
}
}hm[];
int i,j,k,n,m,tx,ty;
int can[][];
ull ans;
char s[];
int v[]; inline void clr(bool now){
memset(hm[now].last,,modd<<),
hm[now].tot=;
} bool u[];int id[],mp[];
inline ull encode(){
memset(u,,);
ull x=;int tt=;
for(int i=;i<=m;mp[i]=id[mp[i]],x=x<<|mp[i],i++)
if(mp[i]&&!u[mp[i]])u[mp[i]]=,id[mp[i]]=++tt;
return x;
}
inline void decode(ull x){
for(int i=m;i>=;i--)mp[i]=x&,x>>=;
}
inline void shift(){
for(int i=m;i;i--)mp[i]=mp[i-];
mp[]=;
} inline void dp_blank(int x,int y,bool pre){
int i,left,up,j;bool now=pre^;ull zt,f;
clr(now);
for(i=;i<=hm[pre].tot;i++){
zt=hm[pre].zt[i],f=hm[pre].f[i],
decode(zt);
left=mp[y-],up=mp[y];
if(!left&&!up){
if(can[x+][y]&&can[x][y+]){
mp[y-]=mp[y]=;
if(y==m)shift();
hm[now].f[ hm[now].get(encode()) ]+=f;
}
if(can[x][y]==){
mp[y-]=mp[y]=;
if(y==m)shift();
hm[now].f[ hm[now].get(encode()) ]+=f;
}
}
if((!left)^(!up)){
j=left|up;
if(can[x+][y]){
mp[y-]=j,mp[y]=;
if(y==m)shift();
hm[now].f[ hm[now].get(encode()) ]+=f;
}
if(can[x][y+]){
mp[y-]=,mp[y]=j;
if(y==m)shift();
hm[now].f[ hm[now].get(encode()) ]+=f;
}
}
if(left&&up){
if(left==up)
if(x>tx||(x==tx&&y>=ty)){
mp[y-]=mp[y]=;
if(encode()==)ans+=f;
}else;
else{
mp[y-]=mp[y]=;
for(j=;j<=m;j++)if(mp[j]==up)mp[j]=left;
if(y==m)shift();
hm[now].f[ hm[now].get(encode()) ]+=f;
}
}
}
}
inline void dp_bar(int x,int y,bool pre){
int i,left,up;bool now=pre^;ull f,zt;
clr(now);
for(i=;i<=hm[pre].tot;i++){
zt=hm[pre].zt[i],f=hm[pre].f[i];
decode(zt);
left=mp[y-],up=mp[y];
if(!left&&!up){
if(y==m)shift();
hm[now].f[ hm[now].get(encode()) ]+=f;
}
}
} int main(){
int TT;
scanf("%d",&TT);v['X']=,v['O']=,v['*']=;
for(int TTT=;TTT<=TT;TTT++){
scanf("%d%d",&n,&m);
memset(can,,sizeof(can));
for(i=;i<=n;i++)
for(scanf("%s",s+),j=;j<=m;j++){
can[i][j]=v[s[j]];
if(s[j]=='O')tx=i,ty=j;
} for(i=n,j=;i;i--){
for(j=m;j;j--)if(can[i][j]==)break;
if(j>)break;
}
tx=i,ty=j; bool now=,pre=;ans=;
clr(),hm[pre].f[ hm[pre].get() ]=;
for(i=;i<=n;i++)for(j=;j<=m;j++,swap(now,pre))
if(can[i][j])dp_blank(i,j,pre);else dp_bar(i,j,pre);
printf("Case %d: %I64u\n",TTT,ans);
}
return ;
}

[FZU1977] Pandora adventure的更多相关文章

  1. FZU1977 Pandora adventure —— 插头DP

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

  2. 【FZU】1977 Pandora adventure

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

  3. FZU 1977 Pandora adventure (DP)

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

  4. FZU 1977 Pandora adventure (插头DP,常规)

    题意:有一个n*m矩阵,其中有些格子必走,有些格子不可走,其他格子是可走也可不走,问有多少条哈密顿回路? 思路: 本来是一道很简单的题,代码写多了连白痴bug都查不出了,竟然用i>=ex& ...

  5. 插头DP专题

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

  6. DP:0

    小故事: A * "1+1+1+1+1+1+1+1 =?" * A : "上面等式的值是多少" B : *计算* "8!" A *在上面等式 ...

  7. 插头dp练习

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

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

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

  9. Java基础-接口看下图实现如下接口和类,并完成Adventure中的主方法

    package hanqi; public interface CanSwim { void swim(); } package hanqi; public interface CanFly { pu ...

随机推荐

  1. iOS 上线因iPv6被拒,查询服务器是否支持iPv6,mac设置iPv6网络,手机测试iPv6

    一. iOS----如何检查域名是否支持ipv6 iOS----------如何检查域名是否支持ipv6 1.检查你所用到的库,像af 3.0以上什么的(不用改),其他的库自己去搜下是否支持ipv6吧 ...

  2. apache故障处理

    注意:修改虚拟机主机html路径不需要修改主配置这一行. DocumentRoot "/var/www" 1.Permission denied: [client 10.10.2. ...

  3. JAVA多线程统计日志计数时的线程安全及效率问题

    最近工作上遇到一个需求:需要根据nginx日志去统计每个域名的qps(Query Per Second,每秒查询率)数据. 解决了日志读取等问题之后,为了写一个尽可能高效的统计模块,我决定用多线程去计 ...

  4. JDK动态代理[1]----代理模式实现方式的概要介绍

    日常工作中经常会接触到代理模式,但一直没有对其进行深究.代理模式一直就像一团迷雾一样存在我心里,什么是代理模式?为什么要使用代理?代理模式有哪些实现?它的底层机制是怎样的?这些问题促使着我迫切想要揭开 ...

  5. Java 哲学家进餐

    某次操作系统实验存档.V 这个哲学家除了吃就知道睡.( ╯□╰ ) 哲学家.java: package operating.entity.philosophyeating; import operat ...

  6. bzoj 1801: [Ahoi2009]chess 中国象棋

    Description 在N行M列的棋盘上,放若干个炮可以是0个,使得没有任何一个炮可以攻击另一个炮. 请问有多少种放置方法,中国像棋中炮的行走方式大家应该很清楚吧. Input 一行包含两个整数N, ...

  7. C# 判断网站是否能访问或者断链

    参考网站:http://www.cnblogs.com/junny/archive/2012/10/30/2745978.html public bool CheckUrlVisit(string u ...

  8. \Process(sqlservr)\% Processor Time 计数器飙高

    计数器" \Process(sqlservr)\% Processor Time",是经常监测,看看SQL Server如何消耗CPU资源.sqlserver是如何利用现有的资源; ...

  9. Python day 6(3) Python 函数式编程1

    一:函数式编程概念 函数是Python内建支持的一种封装,我们通过把大段代码拆成函数,通过一层一层的函数调用,就可以把复杂任务分解成简单的任务,这种分解可以称之为面向过程的程序设计.函数就是面向过程的 ...

  10. openldap 编译报错MozNSS not found

    openldap 编译报错 1)报错 MozNSS not found - please specify the location to the NSPR and NSS header files i ...