插头DP


  楼教主男人八题之一!

  要求从左下角走到右下角的哈密顿路径数量。

  啊嘞,我只会求哈密顿回路啊……这可怎么搞……

  容易想到:要是把起点和重点直接连上就变成一条回路了……那么我们就连一下~

  我们可以在整张图下面加两行:(例:3*5)

  1 1 1 1 1

  1 1 1 1 1

   1 1 1

   0 0 0

  1 1 1 1 1

  红色的是原来的起点和终点,下面紫色的路径将这两个点连了起来= =然后这题瞬间就变回了Formula 1那题……求哈密顿回路数量,so easy有没有~(其实不这样加也可以做,起点终点特判下就可以)

  因为就变成原题了……我就试着默写了一次模板……结果好几个细节给挂了:

  单插头的时候,两种状态转移都要判是否合法的= =!!!(sigh……做了一道HDU 1964直接就傻逼了……因为那题是没有障碍物的……)

  两个插头都没有的时候的转移写错了……(┬_┬)不可以乘p/q的……因为它俩都是0啊……

  程序一开始的时候bit数组的初始化……

 Source Code
Problem: User: sdfzyhy
Memory: 2668K Time: 125MS
Language: G++ Result: Accepted Source Code //POJ 1739
#include<cmath>
#include<vector>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define rep(i,n) for(int i=0;i<n;++i)
#define F(i,j,n) for(int i=j;i<=n;++i)
#define D(i,j,n) for(int i=j;i>=n;--i)
#define pb push_back
#define CC(a,b) memset(a,b,sizeof(a))
using namespace std;
int getint(){
int v=,sign=; char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') sign=-; ch=getchar();}
while(isdigit(ch)) {v=v*+ch-''; ch=getchar();}
return v*sign;
}
const int N=1e7+,INF=~0u>>;
const double eps=1e-;
typedef unsigned long long u64;
/*******************template********************/
const int M=;
bool mp[][];
int n,m,k;
int tot[],bit[],hash[M],state[][M];
u64 dp[][M],ans;
#define debug
void init(){
CC(mp,);
CC(dp,);
tot[]=dp[][]=,ans=k=;
state[][]=;
char ch;
F(i,,n){
scanf("%c",&ch);
F(j,,m){
scanf("%c",&ch);
mp[i][j]=ch=='.';
}
}
n+=;
F(j,,m) mp[n][j]=;
mp[n-][]=mp[n-][m]=;
}
void hash_in(int s,u64 sum){
int p=s%M;
while(hash[p]){
if (state[k][hash[p]]==s){
dp[k][hash[p]]+=sum;
return;
}
p++;
if (p==M) p=;
}
hash[p]=++tot[k];
state[k][hash[p]]=s;
dp[k][hash[p]]=sum;
}
#define in hash_in(s,sum)
void work(){
F(i,,n){
F(j,,m){
k^=;
CC(hash,);
tot[k]=;
F(u,,tot[-k]){
int s=state[-k][u];
u64 sum=dp[-k][u];
int p=(s>>bit[j-])&,q=(s>>bit[j])&;
if (!mp[i][j]){ if (!p && !q) in; }
else{
if (!p && !q){
if (!mp[i+][j] || !mp[i][j+]) continue;
s=s^(<<bit[j-])^(<<bit[j]<<),in;
}else if(!p && q){
if (mp[i][j+]) in;
if (mp[i+][j]) s=s^q*(<<bit[j])^q*(<<bit[j-]),in;
}else if(p && !q){
if (mp[i+][j]) in;
if (mp[i][j+]) s=s^p*(<<bit[j])^p*(<<bit[j-]),in;
}else if(p+q==){
int nd=;
F(u,j+,m){
int w=(s>>bit[u])&;
if (w==) nd++;
if (w==) nd--;
if (!nd){ s-=<<bit[u]; break; }
}s=s^(<<bit[j-])^(<<bit[j]),in;
}else if(p+q==){
int nd=;
D(u,j-,){
int w=(s>>bit[u])&;
if (w==) nd++;
if (w==) nd--;
if (!nd){ s+=<<bit[u]; break; }
}s=s^(<<bit[j-]<<)^(<<bit[j]<<),in;
}else if(p== && q==){
if (i==n && j==m) ans+=sum;
}else if(p== && q==) s=s^(<<bit[j-]<<)^(<<bit[j]),in;
}
}
}
F(j,,tot[k]) state[k][j]<<=;
}
printf("%llu\n",ans);
}
int main(){
#ifndef ONLINE_JUDGE
freopen("input.txt","r",stdin);
// freopen("output.txt","w",stdout);
#endif
F(i,,) bit[i]=i<<;
while(scanf("%d%d",&n,&m)!=EOF && n){
init();
work();
}
return ;
}

【POJ】【1739】Tony's Tour的更多相关文章

  1. 【 POJ - 1204 Word Puzzles】(Trie+爆搜|AC自动机)

    Word Puzzles Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 10782 Accepted: 4076 Special ...

  2. 【POJ 1459 power network】

    不可以理解的是,测评站上的0ms是怎么搞出来的. 这一题在建立超级源点和超级汇点后就变得温和可爱了.其实它本身就温和可爱.对比了能够找到的题解: (1)艾德蒙·卡普算法(2)迪尼克算法(3)改进版艾德 ...

  3. 【POJ 2728 Desert King】

    Time Limit: 3000MSMemory Limit: 65536K Total Submissions: 27109Accepted: 7527 Description David the ...

  4. 【POJ 2976 Dropping tests】

    Time Limit: 1000MSMemory Limit: 65536K Total Submissions: 13849Accepted: 4851 Description In a certa ...

  5. 【POJ 3080 Blue Jeans】

    Time Limit: 1000MSMemory Limit: 65536K Total Submissions: 19026Accepted: 8466 Description The Genogr ...

  6. 【POJ各种模板汇总】(写在逆风省选前)(不断更新中)

    1.POJ1258 水水的prim……不过poj上硬是没过,wikioi上的原题却过了 #include<cstring> #include<algorithm> #inclu ...

  7. 【POJ 3669 Meteor Shower】简单BFS

    流星雨撞击地球(平面直角坐标第一象限),问到达安全地带的最少时间. 对于每颗流星雨i,在ti时刻撞击(xi,yi)点,同时导致(xi,yi)和上下左右相邻的点在ti以后的时刻(包括t)不能再经过(被封 ...

  8. 【POJ 2823 Sliding Window】 单调队列

    题目大意:给n个数,一个长度为k(k<n)的闭区间从0滑动到n,求滑动中区间的最大值序列和最小值序列. 最大值和最小值是类似的,在此以最大值为例分析. 数据结构要求:能保存最多k个元素,快速取得 ...

  9. 【POJ 2406 Power Strings】

    Time Limit: 3000MSMemory Limit: 65536K Description Given two strings a and b we define a*b to be the ...

  10. POJ 1739:Tony's Tour

    Description A square township has been divided up into n*m(n rows and m columns) square plots (1< ...

随机推荐

  1. WampServer修改Mysql密码的步骤

    1.安装成功后,通过 phpmyadmin 进入mysql,点击上面的 [用户] 菜单,在用户[root]主机[localhost]点击编辑权限,下面有一个选项[修改密码],输入您想要的密码,如:12 ...

  2. sql修改字段长度

    语法: alter table <表名> alter column <字段名> 新类型名(长度) 示例:假如有名T1,字段名F1,原来F1为varchar(3),现在要改为va ...

  3. tomcat的OutOfMemoryError(PermGen space)解决方法

    修改TOMCAT_HOME/bin/catalina.bat,在“echo "Using CATALINA_BASE: $CATALINA_BASE"”上面加入以下行: set J ...

  4. 生成HTMLTestRunner测试报告的操作步骤——Python+selenium自动化

    HTMLTestRunner是Python标准库的unittest模块的一个扩展,具体操作如下 1.安装 环境:Window8 步骤:1)http://tungwaiyip.info/software ...

  5. C#操作系统日志

    系统日志可以帮助我们分析操作系统的安全与否,也可以帮助我们将一些不好调试的信息显示出来. C#操作系统日志主要是通过EventLog类来实现的. 一 图解 打开事件查看器,其中与EventLog类对应 ...

  6. 值类型的Constructor

    使用C#的时候我们最熟悉的是类,也就是Reference Type,翻译成中文是引用类型.但是C#还有另外的一种类型往往被我们用的最多缺经常被忽视,这种类型就是值类型(Value Type). 值类型 ...

  7. 在Linux中三种让crontab每秒执行任务的方法

    第一种方法: 1.创建脚本文件 cat phplog.sh 2.编辑脚本内容 #!/bin/bash while : ;do /home/scripts.sh 2>/dev/null & ...

  8. php对数组排序代码

    php对数组排序,介绍了和php,有关的知识.技巧.经验,和一些php源码等. 对数组排序 usort() 函数使用用户自定义的函数对数组排序. */ function cmp($a, $b) //用 ...

  9. 重拾C,一天一点点_4_随想

    刚才顺便又把二分默写了一遍,还好,这次比较顺利.算法这一块,一直是自己一块痛处,有时感觉自己的脑瓜子怎么就这么笨,后一想觉得肯定是锈逗了,确实啊,这么长时间不思考的脑子能机灵到哪呢?早就意识到这个问题 ...

  10. Webserver issues | PHP manager for IIS

    4 down vote accepted In order to successfully install the PHP manager for IIS 8, you need the .NET 3 ...