1519. Formula 1 @ Timus Online Judge

  干了一天啊!!!插头DP入门。

代码如下:

 #include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <ctime>
#include <cmath> using namespace std;
typedef long long LL; const int N = ;
const int M = ;
LL pw[N], dp[][M];
int stk[][M], top[];
char mat[N][N];
bool vis[M]; void PRE() {
pw[] = ;
for (int i = ; i < N; i++) pw[i] = pw[i - ] * ;
} inline int getst(int st, int k) { return st / pw[k] % ;}
inline void print(int st, int n) { for (int i = n; i >= ; i--) printf("%d", getst(st, i));} LL work(int n, int m) {
bool fi = true;
int cur = , ei, ej, nx, st, hi, lo;
memset(dp, , sizeof(dp));
memset(vis, , sizeof(vis));
memset(top, , sizeof(top));
for (int i = ; i < n; i++) for (int j = ; j < m; j++) if (mat[i][j] == '.') ei = i, ej = j;
for (int i = ; i < n; i++) {
for (int j = ; j < m; j++) {
/************* debug ****************/
//cout << i << ' ' << j << ' ' << top[cur] << endl;
//for (int k = 0; k < top[cur]; k++) {
//st = stk[cur][k];
//print(st, m); cout << "~" << dp[cur][st] << ' ';
//}
//cout << endl;
/************************************/
if (i == ei && j == ej) return dp[cur][pw[m] << | ];
for (int k = ; k < top[cur]; k++) vis[stk[cur][k]] = false;
cur ^= ;
for (int k = ; k < top[cur]; k++) dp[cur][stk[cur][k]] = ;
top[cur] = ;
if (mat[i][j] == '*') {
if (fi) continue;
for (int k = ; k < top[cur ^ ]; k++) {
st = stk[cur ^ ][k];
if (getst(st, m)) continue;
nx = st * ;
dp[cur][nx] += dp[cur ^ ][st];
if (!vis[nx]) vis[stk[cur][top[cur]++] = nx] = true;
}
} else {
if (fi) {
dp[cur][] = ;
vis[stk[cur][top[cur]++] = ] = true;
fi = false;
} else {
for (int k = ; k < top[cur ^ ]; k++) {
st = stk[cur ^ ][k];
lo = getst(st, ), hi = getst(st, m);
if (lo == ) {
if (hi == ) {
nx = st * + ;
dp[cur][nx] += dp[cur ^ ][st];
if (!vis[nx]) vis[stk[cur][top[cur]++] = nx] = true;
} else if (hi == ) {
if (i == || mat[i - ][j] == '*') continue;
nx = (st * + ) % pw[m + ];
dp[cur][nx] += dp[cur ^ ][st];
if (!vis[nx]) vis[stk[cur][top[cur]++] = nx] = true;
nx = (st * + ) % pw[m + ];
dp[cur][nx] += dp[cur ^ ][st];
if (!vis[nx]) vis[stk[cur][top[cur]++] = nx] = true;
} else {
if (i == || mat[i - ][j] == '*') continue;
nx = (st * + ) % pw[m + ];
dp[cur][nx] += dp[cur ^ ][st];
if (!vis[nx]) vis[stk[cur][top[cur]++] = nx] = true;
nx = (st * + ) % pw[m + ];
dp[cur][nx] += dp[cur ^ ][st];
if (!vis[nx]) vis[stk[cur][top[cur]++] = nx] = true;
}
} else if (lo == ) {
if (j == || mat[i][j - ] == '*') continue;
if (hi == ) {
nx = st * % pw[m + ];
dp[cur][nx] += dp[cur ^ ][st];
if (!vis[nx]) vis[stk[cur][top[cur]++] = nx] = true;
nx = (st * - ) % pw[m + ];
dp[cur][nx] += dp[cur ^ ][st];
if (!vis[nx]) vis[stk[cur][top[cur]++] = nx] = true;
} else if (hi == ) {
if (i == || mat[i - ][j] == '*') continue;
int cnt = , i = m - , t;
for ( ; i >= ; i--) {
t = getst(st, i);
if (t == ) cnt++;
if (t == ) {
if (cnt) cnt--;
else break;
}
}
nx = (st - pw[i] - ) * % pw[m + ];
//print(st, m); putchar(' '); print(nx, m); puts("");
dp[cur][nx] += dp[cur ^ ][st];
if (!vis[nx]) vis[stk[cur][top[cur]++] = nx] = true;
} else {}
} else {
if (j == || mat[i][j - ] == '*') continue;
if (hi == ) {
nx = st * % pw[m + ];
dp[cur][nx] += dp[cur ^ ][st];
if (!vis[nx]) vis[stk[cur][top[cur]++] = nx] = true;
nx = (st * - ) % pw[m + ];
dp[cur][nx] += dp[cur ^ ][st];
if (!vis[nx]) vis[stk[cur][top[cur]++] = nx] = true;
} else if (hi == ) {
if (i == || mat[i - ][j] == '*') continue;
nx = st / * % pw[m + ];
dp[cur][nx] += dp[cur ^ ][st];
if (!vis[nx]) vis[stk[cur][top[cur]++] = nx] = true;
} else {
if (i == || mat[i - ][j] == '*') continue;
int cnt = , i = , t;
for ( ; i <= m; i++) {
t = getst(st, i);
if (t == ) cnt++;
if (t == ) {
if (cnt) cnt--;
else break;
}
}
nx = (st + pw[i] - ) * % pw[m + ];
dp[cur][nx] += dp[cur ^ ][st];
if (!vis[nx]) vis[stk[cur][top[cur]++] = nx] = true;
}
}
}
}
}
}
}
return ;
} int main() {
//freopen("in", "r", stdin);
//freopen("out", "w", stdout);
//time_t t1 = clock();
int n, m;
PRE();
//cout << (double) (clock() - t1) / CLOCKS_PER_SEC << endl;
while (cin >> n >> m) {
for (int i = ; i < n; i++) { for (int j = ; j < m; j++) cin >> mat[i][j]; mat[i][m] = ;}
cout << work(n, m) << endl;
//cout << (double) (clock() - t1) / CLOCKS_PER_SEC << endl;
}
return ;
}

——written by Lyon

ural 1519 Formula 1(插头dp)的更多相关文章

  1. 【BZOJ1814】Ural 1519 Formula 1 插头DP

    [BZOJ1814]Ural 1519 Formula 1 题意:一个 m * n 的棋盘,有的格子存在障碍,求经过所有非障碍格子的哈密顿回路个数.(n,m<=12) 题解:插头DP板子题,刷板 ...

  2. bzoj1814 Ural 1519 Formula 1(插头dp模板题)

    1814: Ural 1519 Formula 1 Time Limit: 1 Sec  Memory Limit: 64 MBSubmit: 924  Solved: 351[Submit][Sta ...

  3. bzoj 1814 Ural 1519 Formula 1 插头DP

    1814: Ural 1519 Formula 1 Time Limit: 1 Sec  Memory Limit: 64 MBSubmit: 942  Solved: 356[Submit][Sta ...

  4. bzoj 1814 Ural 1519 Formula 1 ——插头DP

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1814 普通的插头 DP .但是调了很久.注意如果合并两个 1 的话,不是 “把向右第一个 2 ...

  5. Ural 1519 Formula 1 插头DP

    这是一道经典的插头DP单回路模板题. 用最小表示法来记录连通性,由于二进制的速度,考虑使用8进制. 1.当同时存在左.上插头的时候,需要判断两插头所在连通块是否相同,若相同,只能在最后一个非障碍点相连 ...

  6. BZOJ1814: Ural 1519 Formula 1(插头Dp)

    Description Regardless of the fact, that Vologda could not get rights to hold the Winter Olympic gam ...

  7. bzoj 1814: Ural 1519 Formula 1 插头dp经典题

    用的括号序列,听说比较快. 然并不会预处理,只会每回暴力找匹配的括号. #include<iostream> #include<cstdio> #include<cstr ...

  8. 【Ural】1519. Formula 1 插头DP

    [题目]1519. Formula 1 [题意]给定n*m个方格图,有一些障碍格,求非障碍格的哈密顿回路数量.n,m<=12. [算法]插头DP [题解]<基于连通性状态压缩的动态规划问题 ...

  9. 【BZOJ1814】Ural 1519 Formula 1 (插头dp)

    [BZOJ1814]Ural 1519 Formula 1 (插头dp) 题面 BZOJ Vjudge 题解 戳这里 上面那个链接里面写的非常好啦. 然后说几个点吧. 首先是关于为什么只需要考虑三进制 ...

随机推荐

  1. 洛谷 P1036 选数【背包型DFS/选or不选】

    题目描述 已知 n 个整数 x1,x2,…,xn,以及一个整数 k(k<n).从 n 个整数中任选 k 个整数相加,可分别得到一系列的和.例如当 n=4,k=3,4 个整数分别为 3,7,12, ...

  2. java图形验证码生成工具类及web页面校验验证码

    最近做验证码,参考网上案例,发现有不少问题,特意进行了修改和完善. 验证码生成器: import javax.imageio.ImageIO; import java.awt.*; import ja ...

  3. 【洛谷P1632】点的移动

    P1632 点的移动 题目描述 平面上有N个整数坐标点.如果将点(x0,y0)移动到(x1,y1),则需要的代价为|x0-x1|+|y0-y1|.求使得K(K=1,-,N)个点在同一位置上最少需要的代 ...

  4. json原生解析

    身为新手,在运用网络解析json数据的时候,发现先会用Gson等框架解析json,然后就懒起来学原生解析了,这下在看别人写的demo的时候就尴尬了,一块块的,不懂写什么,气氛十分尴尬. 不多说,先来条 ...

  5. 转:Android新特性介绍,ConstraintLayout完全解析

    转:http://blog.csdn.net/guolin_blog/article/details/53122387 本篇文章的主题是ConstraintLayout.其实ConstraintLay ...

  6. 7. 18 test 砍树题解

    (题面保密,内部人员可览) 首先观察题面,可得出如下公式 ∑(ceil(a[i] /d)*d−a[i])≤k 其中,ceil(a[i] /d)表示在需要被砍伐之前所经过的轮数,ceil函数是为了保证一 ...

  7. Keil新建工程步骤

    第一步:创建工程文件夹 1.新建一个文件夹,例如: 2.在文件夹下创建子文件夹: 文件夹说明: App:存放硬件控制程序: Libraries:存放固件库: Obj:存放生成的文件: Public:存 ...

  8. 计算机网络3.2&3.3(第二节介质&第三节多路复用)

    有限的传播介质 双绞线 双绞线电缆 双绞线总结 2 同轴电缆 粗细电缆的传输距离 现在基本都用双绞线和光线 同轴电缆用于居民小区和家庭使用 3 光纤 光纤中以光信号的形式进行传播 正如我们现在看到这样 ...

  9. python ndarray相关操作:索引

  10. database homework3

    查询所有大于60分的学生的姓名和学号 (DISTINCT: 去重) mysql> select student.sname,student.sid,score.number from stude ...