http://acm.hdu.edu.cn/showproblem.php?pid=1693

题意:n×m的棋盘求简单回路(可以多条)覆盖整个棋盘的方案,障碍格不许摆放。(n,m<=11)

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; typedef long long ll;
struct H {
static const int M=1000007;
struct E { int next, to; }e[M<<1];
int ihead, cnt, hash[M];
ll sum[M];
H() { ihead=cnt=0; memset(hash, -1, sizeof hash); memset(sum, 0, sizeof sum); }
bool find(int x, int &pos) {
pos=x%M;
while(1) { if(hash[pos]==x) return false; if(hash[pos]==-1) break; ++pos; if(pos==M) pos=0; }
hash[pos]=x; return true;
}
void ins(int a, ll b) {
int pos; if(!find(a, pos)) { sum[pos]+=b; return; }
e[++cnt].next=ihead; ihead=cnt; e[cnt].to=pos; sum[pos]=b;
}
void clr() { for(int i=ihead; i; i=e[i].next) hash[e[i].to]=-1, sum[e[i].to]=0; ihead=cnt=0; }
}T1, T2; #define BIT(a,b) ((a)<<((b)<<1))
#define CLR(a,b) (a^=((a)&BIT(3,b)))
#define GET(a,b) (3&((a)>>((b)<<1))) const int N=11;
int n, m;
ll ans;
bool mp[N][N]; int find(int s, int col, int flag) {
int sum=0;
if(flag) {
for(int i=col; i<=m; ++i) {
int k=GET(s, i);
if(k==1) ++sum;
if(k==2) --sum;
if(!sum) return i;
}
}
else {
for(int i=col; i>=0; --i) {
int k=GET(s, i);
if(k==1) --sum;
if(k==2) ++sum;
if(!sum) return i;
}
}
return -1;
}
void print(int s) {
for(int i=0; i<=m; ++i) { int k=GET(s, i); if(k==0) putchar('#'); else if(k==1) putchar('('); else if(k==2) putchar(')'); }
puts("");
}
#define F puts("error");
bool next(int s, int row, int col, bool U, bool D, bool L, bool R, int &t) {
if((row==n-1&&D) || (row==0&&U) || (col==m-1&&R) || (col==0&&L)) return 0;
if((D&&!mp[row+1][col]) || (R&&!mp[row][col+1])) return 0;
int l=GET(s, col), u=GET(s, col+1), d=0, r=0;
// printf("State:"); print(s);
// printf("row:%d, col:%d, U:%d, D:%d, L:%d, R:%d ", row, col, U, D, L, R);
// printf(" left:"); if(l==1) printf("("); if(l==2) printf(")"); if(l==0) printf("#");
// printf(" uptp:"); if(u==1) printf("("); if(u==2) printf(")"); if(u==0) printf("#"); puts("");
if((l&&!L) || (!l&&L) || (u&&!U) || (!u&&U)) return 0;
t=s; //puts("============\nfirst:"); print(t);
CLR(t, col);
CLR(t, col+1);
if(!l && !u) {
if(R && D) d=1, r=2;
}
else if(l && u) {
if(l==1 && u==1) {
int pos=find(s, col+1, 1);
CLR(t, pos);
t|=BIT(1, pos);
}
else if(l==2 && u==2) {
int pos=find(s, col, 0);
CLR(t, pos);
t|=BIT(2, pos);
}
}
else if(l && !u) {
if(D) d=l, r=0;
if(R) d=0, r=l;
}
else if(!l && u) {
if(D) d=u, r=0;
if(R) d=0, r=u;
}
t|=BIT(d, col);
t|=BIT(r, col+1);
if(col==m-1) t<<=2; //puts("=============\nnext"); print(t);
return 1;
} void bfs() {
H *q1, *q2;
q1=&T1; q2=&T2;
q1->clr();
q2->clr();
q1->ins(0, 1);
for(int row=0; row<n; ++row) for(int col=0; col<m; ++col) {
q2->clr(); //printf("q1->cnt:%d\n", q1->cnt);
for(int i=q1->ihead; i; i=q1->e[i].next) {
int s=q1->hash[q1->e[i].to], t; //print(s); //这里犯逗了啊.....我一开始竟然没写hash这个....我去...
ll sum=q1->sum[q1->e[i].to];
if(!mp[row][col]) { if(next(s, row, col, 0, 0, 0, 0, t)) q2->ins(t, sum); }
else {
if(next(s, row, col, 1, 1, 0, 0, t)) q2->ins(t, sum);
if(next(s, row, col, 1, 0, 1, 0, t)) q2->ins(t, sum);
if(next(s, row, col, 1, 0, 0, 1, t)) q2->ins(t, sum);
if(next(s, row, col, 0, 1, 1, 0, t)) q2->ins(t, sum);
if(next(s, row, col, 0, 1, 0, 1, t)) q2->ins(t, sum);
if(next(s, row, col, 0, 0, 1, 1, t)) q2->ins(t, sum);
}
}
swap(q1, q2);
}
for(int i=q1->ihead; i; i=q1->e[i].next) ans+=q1->sum[q1->e[i].to];
} int main() {
int cs, temp; scanf("%d", &cs);
for(int cc=1; cc<=cs; ++cc) {
ans=0;
scanf("%d%d", &n, &m);
for(int i=0; i<n; ++i) for(int j=0; j<m; ++j) {
scanf("%d", &temp);
mp[i][j]=temp;
}
bfs();
printf("Case %d: There are %lld ways to eat the trees.\n", cc, ans);
}
return 0;
}

  


犯逗了啊啊啊啊啊啊啊啊啊啊...本来一裸的插头dp...............

我竟然在调用hash的时候忘记套会实际值了啊啊啊啊啊啊啊..........

调了1h啊啊啊啊啊啊.....................

然后本题就是上一题随便改一改就行了...

【HDU】1693 Eat the Trees的更多相关文章

  1. 【HDU】1693:Eat the Trees【插头DP】

    Eat the Trees Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tot ...

  2. 【HDU】4888 Redraw Beautiful Drawings 网络流【推断解是否唯一】

    传送门:pid=4888">[HDU]4888 Redraw Beautiful Drawings 题目分析: 比赛的时候看出是个网络流,可是没有敲出来.各种反面样例推倒自己(究其原因 ...

  3. hdu 1693 : Eat the Trees 【插头dp 入门】

    题目链接 题意: 给出一个n*m大小的01矩阵,在其中画线连成封闭图形,其中对每一个值为1的方格,线要恰好穿入穿出共两次,对每一个值为0的方格,所画线不能经过. 参考资料: <基于连通性状态压缩 ...

  4. hdu 1693 Eat the Trees——插头DP

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=1693 第一道插头 DP ! 直接用二进制数表示状态即可. #include<cstdio> # ...

  5. HDU 1693 Eat the Trees ——插头DP

    [题目分析] 吃树. 直接插头DP,算是一道真正的入门题目. 0/1表示有没有插头 [代码] #include <cstdio> #include <cstring> #inc ...

  6. HDU 1693 Eat the Trees(插头DP、棋盘哈密顿回路数)+ URAL 1519 Formula 1(插头DP、棋盘哈密顿单回路数)

    插头DP基础题的样子...输入N,M<=11,以及N*M的01矩阵,0(1)表示有(无)障碍物.输出哈密顿回路(可以多回路)方案数... 看了个ppt,画了下图...感觉还是挺有效的... 参考 ...

  7. HDU 1693 Eat the Trees(插头DP)

    题目链接 USACO 第6章,第一题是一个插头DP,无奈啊.从头看起,看了好久的陈丹琦的论文,表示木看懂... 大体知道思路之后,还是无法实现代码.. 此题是插头DP最最简单的一个,在一个n*m的棋盘 ...

  8. HDU 1693 Eat the Trees

    第一道(可能也是最后一道)插头dp.... 总算是领略了它的魅力... #include<iostream> #include<cstdio> #include<cstr ...

  9. HDU - 1693 Eat the Trees(多回路插头DP)

    题目大意:要求你将全部非障碍格子都走一遍,形成回路(能够多回路),问有多少种方法 解题思路: 參考基于连通性状态压缩的动态规划问题 - 陈丹琦 下面为代码 #include<cstdio> ...

随机推荐

  1. LSM-Tree (BigTable 的理论模型)(转)

    Google的BigTable架构在分布式结构化存储方面大名鼎鼎,其中的MergeDump模型在读写之间找到了一个较好的平衡点,很好的解决了web scale数据的读写问题. MergeDump的理论 ...

  2. 10g ASM下修改control file的位置

    1.查看位置以及name是否正确 SQL> sho parameter name NAME TYPE VALUE ------------------------------------ --- ...

  3. POJ 3140 Contestants Division 树形DP

    Contestants Division   Description In the new ACM-ICPC Regional Contest, a special monitoring and su ...

  4. Windows硬件断点-实现单步异常

    触犯单步异常 改变的是当前Eflags 而不是触发异常的Eflags 也就是 PUSHF MOV EAX, DWORD PTR[ESP]       OR EAX, 0x100       MOV D ...

  5. 【项目经验】navicat工具 SQLServer数据库迁移MySQL

    新近领了一个任务,就是把SQL Server的数据库迁移到My Sql上,经过查资料,圆满完成任务.分享一下流程. 1.首先,在自己的My Sql数据库上新建一个数据库. 2.打开新建的My Sql数 ...

  6. LoadRunner参数化之数据生成方式

    一般需要使用多条数据来完成实际事务的时候,需要参数化.而使用参数化可以方便实现很多实际事务,记得在哪里看到过,参数化是比C函数更高级的函数. 参数化的方法 先来个最常见的LR示例的登录脚本: Acti ...

  7. Android 使用 LruCache 缓存图片

    在你应用程序的 UI 界面加载一张图片是一件很简单的事情,但是当你需要在界面上加载一大堆图片的时候,情况就变得复杂起来.在很多情况下,(比如使用 ListView, GridView 或者 ViewP ...

  8. Spring的Lifecycle

    Lifecycle接口定义了每个对象的重要方法,每个对象都有自己的生命周期需求,如下: public interface Lifecycle { void start(); void stop(); ...

  9. POJ 3080 后缀数组/KMP

    题目链接:http://poj.org/problem?id=3080 题意:给定n个DNA串,求最长公共子串.如果最长公共子串的长度小于3时输出no significant commonalitie ...

  10. 移动开单扫描终端-全触屏互联网安卓打印扫描 PDAPOS机——开单扫描POS-移动开单扫描POS

    浩瀚云POS是一款自主研发的全触屏互联网POS,一贯以领先的技术.快捷友好的用户体验和在全国广泛覆盖的网络,为电子商务.提供安全.可靠.保密的数据校验服务.作为其研发的一款专业移动开单扫描终端. 互联 ...