今天早上学了插头DP的思想和最基础的应用,中午就开始敲了,岐哥说第一次写不要看别人代码,利用自己的理解一点点得写出来,这样才锻炼代码能力!于是下午慢慢地构思轮廓,一点点地敲出主体代码,其实是很磨蹭的,由于要考虑好多东西,而且昨晚2点睡的有点困,最后终于磨蹭出来了,第一次的代码搓没关系,自己写的才重要。然后果然不出我所料,调试到了晚上才A了(一个郁闷的错误)。。。A的感觉真的是爽呀,虽然搞了差不多一天。当然自己写了自己想的代码后也要把代码优化,不然队友看不懂自己代码就囧了。。。

插头DP,建议大家想学的好好看看陈丹琦的国家集训队论文,这是个优美的DP。

http://www.docin.com/p-46797997.html

#include <stdio.h>
#include <string.h>#define LL __int64const int mod = 10007;//   哈希表
struct HASH{int head[mod+10], E, next[80000];LL val[80000], cnt[80000];void init() {memset(head, -1, sizeof(head));E = 0;}int findhash(LL x) {return (x%mod + mod)%mod;}void add(LL x, LL sum) {int u = findhash(x);for(int i = head[u];i != -1;i = next[i]) if(val[i] == x) {cnt[i] += sum;return ;}val[E] = x;cnt[E] = sum;next[E] = head[u];head[u] = E++;}}biao1, biao2;int c[22], n, m, d[22];
//  编码
void get(LL x) {for(int i = m+1;i >= 1; i--) {c[i] = x&7;x /= 8;}
}
//  解码
LL getval() {LL ret = 0;for(int i = 1;i <= m+1; i++) {ret |= d[i];ret *= 8;}ret /= 8;return ret ;
}
//   转化成最小表示法
void change() {int vis[22];memset(vis, 0, sizeof(vis));int num = 1;for(int i = 1;i <= m+1;i ++) {if(!d[i])   continue;if(!vis[d[i]]) {vis[d[i]] = num;d[i] = num++;}else {d[i] = vis[d[i]];}}
}void fuzhi() {for(int i = 1;i <= m+1;i ++)    d[i] = c[i];
}char s[22][22];int main() {int i, j, k, l;while(scanf("%d%d", &n, &m) != -1) {for(i = 1;i <= n; i++)scanf("%s", s[i]+1);int tot = 0;for(i = 1;i <= n; i++)for(j = 1;j <= m; j++)if(s[i][j] == '.')  tot++;if(tot%2==1 || tot < 4) {puts("0");continue;}int tox  = -1, toy = -1;for(i = 1;i <= n; i++)for(j = 1;j <= m; j++) if(s[i][j] == '.') {tox = i;toy = j;}biao1.init();biao1.add(0, 1);LL ans = 0;for(i = 1;i <= n; i++){for(j = 0;j <= m; j++){biao2.init();for(l = 0;l < biao1.E; l++)  {get(biao1.val[l]);if(j == m) {for(int ii = 2;ii <= m+1; ii++) d[ii] = c[ii-1];d[1] = 0;change();LL now = getval();biao2.add(now, biao1.cnt[l]);continue;}if(c[j+1] && !c[j+2]) {  //  有左插头无上插头if(s[i][j+1] != '.')  continue;if(j+2 <= m) {fuzhi();d[j+1] = 0;d[j+2] = c[j+1];change();LL now = getval();biao2.add(now, biao1.cnt[l]);}if(i < n) {fuzhi();change();LL now = getval();biao2.add(now, biao1.cnt[l]);}}else if(!c[j+1] && c[j+2]) {  //  有上插头无左插头if(s[i][j+1] != '.')  continue;if(i < n) {fuzhi();d[j+1] = c[j+2]; d[j+2] = 0;change();LL now = getval();biao2.add(now, biao1.cnt[l]);}if(j+2 <= m) {fuzhi();change();LL now = getval();biao2.add(now, biao1.cnt[l]);}}else if(!c[j+1] && !c[j+2]) { //   左和上都无插头if(s[i][j+1] != '.') {fuzhi();change();LL now = getval();biao2.add(now, biao1.cnt[l]);continue;}if(j+2 <= m && i < n) {fuzhi();d[j+1] = d[j+2] = 13;change();LL now = getval();biao2.add(now, biao1.cnt[l]);}}else { //  左和上都有插头 ,  要判断左和上插头是否连通if(c[j+2] == c[j+1]) {int tot = 0;for(int ii = 1;ii <= m+1; ii++) if(c[ii])tot++;if(tot == 2 && i == tox && j+1 == toy) ans += biao1.cnt[l];}else {if(s[i][j+1] != '.')    continue;fuzhi();for(int ii = 1;ii <= m+1; ii++) if(ii != j+1 && ii != j+2 && d[ii] == d[j+1]) {d[ii] = d[j+2];break;}d[j+1] = d[j+2] = 0;change();LL now = getval();biao2.add(now, biao1.cnt[l]);}}}biao1 = biao2;}}printf("%I64d\n", ans);}return 0;
}

转载于:https://www.cnblogs.com/jiangu66/p/3236833.html

Ural 1519. Formula 1 优美的插头DP相关推荐

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

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

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

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

  3. BZOJ 1814 Ural 1519 Formula 1

    题目链接 https://www.lydsy.com/JudgeOnline/problem.php?id=1814 题解 插头dp,枚举边界线的插头,分类讨论转移点上插头和左插头的情况,来转移这个点 ...

  4. bzoj 1814: Ural 1519 Formula 1【插头dp】

    设f[i][j][s]为轮廓线推到格子(i,j),状态为s的方案数 括号表示一段线的左端和右端,表示成左括号和右括号,状压的时候用1和2表示,0表示已经闭合 下面的蓝线是黄色格子的轮廓线,dp转移要把 ...

  5. 插头DP题目泛做(为了对应WYD的课件)

    题目1:BZOJ 1814 URAL 1519 Formula 1 题目大意:给定一个N*M的棋盘,上面有障碍格子.求一个经过所有非障碍格子形成的回路的数量. 插头DP入门题.记录连通分量. 1 #i ...

  6. POJ-1739 Tony's Tour 插头DP(单条路径)

    题目链接:http://poj.org/problem?id=1739 完全可以用Ural 1519 Formula 1 插头DP(单回路)的代码解决此题,只要把图修改一下: .... ....... ...

  7. URAL1519 Formula 1 —— 插头DP

    题目链接:https://vjudge.net/problem/URAL-1519 1519. Formula 1 Time limit: 1.0 second Memory limit: 64 MB ...

  8. [入门向选讲] 插头DP:从零概念到入门 (例题:HDU1693 COGS1283 BZOJ2310 BZOJ2331)

    转载请注明原文地址:http://www.cnblogs.com/LadyLex/p/7326874.html 最近搞了一下插头DP的基础知识--这真的是一种很锻炼人的题型-- 每一道题的状态都不一样 ...

  9. HDU4084 插头dp

    题意:给定一个图,0是不能放的,然后现在有1X1和1X2方块,最后铺满该图,使得1X1使用次数在C到D之间,1X2次数随便,问有几种放法 思路:插头DP或轮廓线,多加一维DP讨论就可以 注意插头DP状 ...

最新文章

  1. 2006年下半年 网络工程师 上下午试卷【附带答案】
  2. R创建哑变量(Dummy Variables)
  3. 华为诺亚加法网络再升级:精度提升,可以逼近任意函数
  4. JEECG微云快速开发平台
  5. 我们用Windows官方跑了跑Linux GUI应用程序,不愧是“胶水操作系统”
  6. Shell declare的使用方法
  7. QuickHit游戏
  8. Unix操作系统基础:Unix文件系统之文件权限
  9. linux下thinkpad X1 carbon 2018 电源管理
  10. 安全电子签章密码技术规范_最新|8项网络安全国家标准详情公布!10月1日正式实施(附8项标准全文)...
  11. java公告栏源码_公告栏view
  12. 就业面试的时候,hr会不会去确定程序员的学历?
  13. 5000字、12字 连环炮、一张图快速解决线程池
  14. 写代码到底应该买什么键盘?
  15. canvas在图片上标记后保存到后台
  16. Unity游戏存档的四种方式
  17. CUMT矿大----电路与数字系统实验四 计数、译码、显示的HDL设计
  18. 如何在CSDN-markdown编辑器写新文章上传图片的时候去掉水印
  19. 线段树模板(来自胡浩大牛)
  20. CAD如何导出JPG高清图片

热门文章

  1. 5个能提高你工作效率的Excel技巧
  2. 挑战程序设计竞赛 (秋叶拓哉 / 岩田阳一 / 北川宜稔 著)
  3. vue用阿里云oss上传图片使用分片上传只能上传100kb以内的解决办法
  4. polymer web componets 大前端
  5. The credentials you provided during SQL Server 2008 install are invalid
  6. Hibernate初学之CURD
  7. php 逗号 分割字符串
  8. 引发类型为“System.Windows.Forms.AxHost+InvalidActiveXStateException”的异常 解决
  9. 开始→运行→输入的命令集锦( 菜鸟必读)
  10. 真格量化——做空波动率卖期权策略