ZOJ 3466 The Hive II (插头DP,变形)
题意:有一个n*8的蜂房(6边形的格子),其中部分是障碍格子,其他是有蜂蜜的格子,每次必须走1个圈取走其中的蜂蜜,在每个格子只走1次,且所有蜂蜜必须取走,有多少种取法?

思路:
以前涉及的只是n*m的矩阵,也就是四边形的,现在变成了6边形,那么每个格子也就有6个方向可以出/进。为了方便考虑,将蜂房变成按列来扫,那么轮廓线需要2*n+1个插头信息。这里不需要用到括号表示法或者最小表示法,只需要表示该位置是否有线即可,所以每个插头仅需1个位就可以表示了。
转置一下后的蜂房应该是这样的:

轮廓线是一个左,一个左上,一个右上来组成的。当前格子为奇数行时,状态需要左移2位,因为有两个方向(左,左上)是空出来的。其他的只需要根据奇偶数行来判断即可。
2700ms+
#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=;
int g[N][N], cur, n, m;
struct Hash_Map
{
static const int mod=;
static const int NN=; //至少50万
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)
{
return ((s>>pos)&);
} inline LL setbit(LL s,int pos,int bit)
{
s&=~((LL)<<pos);
return (s|(LL)bit<<pos);
} void DP(int i,int j)
{
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), DL=getbit(s,*j+), DR=getbit(s,*j+);
LL t=(setbit(s,*j+,)&setbit(s,*j+,)&setbit(s,*j+,));
if(g[i][j]==) //必走格子
{
if( R && DL && DR ) continue; //3个插头,冲突了。
if( R && DL || R && DR || DL && DR ) hashmap[cur].insert(t,v); //合并
else if( R || DL || DR ) //延续
{
if( j+<m ) hashmap[cur].insert(setbit(t,*j+,), v); //右
if( i+<n )
{
if( !(i&) || j+<m ) hashmap[cur].insert(setbit(t,*j+,), v); //右下
if( (i&) || j> ) hashmap[cur].insert(setbit(t,*j+,), v); //左下
}
}
else //新插头
{
if(i+<n)
{
if( (j>&&!(i&)) || (j+<m&&(i&)) ) //(左下,右下)
hashmap[cur].insert( setbit(s,*j+,)|setbit(s,*j+,), v);
if( j+<m )
{
if( (i&) || j> ) //(左下,右)
hashmap[cur].insert( setbit(s,*j+,)|setbit(s,*j+,), v);
if( !(i&) || j+<m ) //(右下,右)
hashmap[cur].insert( setbit(s,*j+,)|setbit(s,*j+,), v);
}
}
}
}
else if(R+DL+DR==) hashmap[cur].insert(s,v); //障碍格子
}
} void cal()
{
cur=;
hashmap[cur].clear();
hashmap[cur].insert(,);
for(int i=; i<n; i++)
{
if( !(i&) ) //只有奇数行才需要左移
{
for(int k=; k<hashmap[cur].size; k++) hashmap[cur].status[k]<<=;
}
for(int j=; j<m; j++)
{
cur^=;
hashmap[cur].clear();
DP(i,j);
}
}
}
LL print()
{
for(int i=; i<hashmap[cur].size; i++)
if(hashmap[cur].status[i]==)
return hashmap[cur].value[i];
return ;
} int main()
{
freopen("input.txt", "r", stdin);
while(~scanf("%d%d",&n,&m))
{
memset(g, , sizeof(g));
char c1,c2;
for(int i=; i<m; i++)
{
c1=getchar();
while(!isalpha(c1)) c1=getchar();
c2=getchar();
while(!isalpha(c2)) c2=getchar();
g[c2-'A'][c1-'A']=; //1为障碍格子
}
m=;
swap(n,m);
for(int i=; i*<n; i++)
{
for(int j=; j<m; j++)
swap(g[i][j],g[n--i][j]);
} cal();
printf("%lld\n", print() );
}
return ;
}
AC代码
ZOJ 3466 The Hive II (插头DP,变形)的更多相关文章
- ZOj 3466 The Hive II
There is a hive in the village. Like this. There are 8 columns(from A to H) in this hive. Different ...
- 插头DP专题
建议入门的人先看cd琦的<基于连通性状态压缩的动态规划问题>.事半功倍. 插头DP其实是比较久以前听说的一个东西,当初是水了几道水题,最近打算温习一下,顺便看下能否入门之类. 插头DP建议 ...
- ZOJ 3256 Tour in the Castle 插头DP 矩阵乘法
题解 这题是一道非常好的插头题,与一般的按格转移的题目不同,由于m很大,要矩阵乘法,这题需要你做一个按列转移的插头DP. 按列转移多少与按格转移不同,但大体上还是基于连通性进行转移.每一列只有右插头是 ...
- HDU 3377 Plan (插头DP,变形)
题意:有一个n*m的矩阵,每个格子中有一个值(可能负值),要从左上角走到右下角,求路径的最大花费. 思路: 除了起点和终点外,其他的点可以走,也可以不走. (2)我用的是括号表示法,所以起始状态为') ...
- Ural 1519. Formula 1 优美的插头DP
今天早上学了插头DP的思想和最基础的应用,中午就开始敲了,岐哥说第一次写不要看别人代码,利用自己的理解一点点得写出来,这样才锻炼代码能力!于是下午慢慢地构思轮廓,一点点地敲出主体代码,其实是很磨蹭的, ...
- [入门向选讲] 插头DP:从零概念到入门 (例题:HDU1693 COGS1283 BZOJ2310 BZOJ2331)
转载请注明原文地址:http://www.cnblogs.com/LadyLex/p/7326874.html 最近搞了一下插头DP的基础知识……这真的是一种很锻炼人的题型…… 每一道题的状态都不一样 ...
- 【HDU】1693:Eat the Trees【插头DP】
Eat the Trees Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tot ...
- 插头dp练习
最近学了插头dp,准备陆续更新插头dp类练习. 学习论文还是cdq那篇<基于连通性状态压缩的动态规划问题>. 基本的想法都讲得很通透了,接下来就靠自己yy了. 还有感谢kuangbin大大 ...
- HDU 1693 Eat the Trees(插头DP,入门题)
Problem Description Most of us know that in the game called DotA(Defense of the Ancient), Pudge is a ...
随机推荐
- AngularJS系统学习之$watch(监控)
在scope的内置的所有函数中,用的最多的可能就是$watch函数了, 当你的数据模型中某一部分发生变化时,$watch函数可以向你发出通知. 你可以监控单个对象的属性,亦可以监控需要经过计算的结果( ...
- Mertens
题意: 求解$\sum_{i=a}^b{\mu(i)}$. 解法: 由$(\mu * I)(n) = e(n)$ 得 $\sum_{d|n}{\mu(d)} = [n=1]$ 得 $\mu(n) = ...
- jsoup解析xml某片段的问题
参考: http://blog.csdn.net/qy20115549/article/details/53556928 <tr> <td class='center'> &l ...
- lua中文教程【基本语法】
代码例子:http://www.inf.puc-rio.br/~roberto/book/code.html 注意:没有“:” 1.特点:可扩展.简单.高效.跨平台 2.使用方式:嵌入程序.独立使用. ...
- POJ3696【欧拉函数+欧拉定理】
题意: 求最小T,满足L的倍数且都由8组成,求长度: 思路: 很强势的福利:点 图片拿出去食用更优 //#include<bits/stdc++.h> #include<cstdio ...
- mysql 5.6 安装x64版本
从mysql下载的 32bit的 msi installer 后 , 安装的时候没有发现选择x64的地方, 最后安装完毕后发现server是32bit的,只能删除server( installer ...
- 2014-10-23 NOIP模拟赛
NOIP2014模拟赛 -----lwher 时限均为1s,内存 256MB 1.Jams倒酒(pour) Jams是一家酒吧的老板,他的酒吧提供2种体积的啤酒,a ml 和 b ml,分别使用容积为 ...
- Spark 学习(三) maven 编译spark 源码
spark 源码编译 scala 版本2.11.4 os:ubuntu 14.04 64位 memery 3G spark :1.1.0 下载源码后解压 1 准备环境,安装jdk和scala,具体参考 ...
- 浅谈Nginx服务器的内部核心架构设计
前言 Nginx 是一个 免费的 , 开源的 , 高性能 的 HTTP 服务器和 反向代理 ,以及 IMAP / POP3代理服务器. Nginx 以其高性能,稳定性,丰富的功能,简单的配置和低资源消 ...
- github 收藏项目的方法
1,Watching 需要收藏的项目 2,查看收藏的项目