【题目大意】

给出一个网格,经过边要付出代价。求走过每一个格子的欧拉回路的最小代价。
【思路】

裸裸的插头DP~然而写了好久orz

【错误点】

整个人跟制杖了一样QAQ

hash实力写挂…m和n搞反了。具体看注释。

 #include<bits/stdc++.h>
#define u 0
#define d 1
#define l 2
#define r 3
using namespace std;
typedef long long ll;
const int MAXN=;
const int HASH=;
struct Hashmap
{
vector<int> hash[HASH];
vector<ll> state,f;
void clear()
{
for (int i=;i<HASH;i++) vector<int>().swap(hash[i]);
vector<ll>().swap(state);
vector<ll>().swap(f);
} void push(ll st,ll ans)
{
int now=st%HASH;
for (int i=;i<hash[now].size();i++)
{
int h=hash[now][i];
if (state[h]==st) //st写成了now QAQ下面return还忘记写到大括号里面去了,浪费了3个小时查orz
{
f[h]=min(f[h],ans);
return;
}
}
hash[now].push_back(state.size());
state.push_back(st);
f.push_back(ans);
}
}dp[];
int m,n;
int maze[MAXN][MAXN][],code[MAXN];//上下左右
int ch[MAXN]; void decode(ll st)
{
for (int i=n;i>=;i--)
{
code[i]=st&;
st>>=;
}
} ll encode()
{
ll ret=;
int cnt=;
memset(ch,-,sizeof(ch));
ch[]=;
for (int i=;i<=n;i++)
{
if (ch[code[i]]==-) ch[code[i]]=++cnt;
code[i]=ch[code[i]];
ret<<=;
ret+=code[i];
}
return ret;
} void shift()
{
for (int i=n;i>;i--) code[i]=code[i-];
code[]=;
} void dpblank(int i,int j,int cur)
{
for (int k=;k<dp[-cur].state.size();k++)
{
decode(dp[-cur].state[k]);
if (j==)
{
if (code[n]!=) continue;
else shift();
}
int left=code[j-],up=code[j];//left和up要等到shift之后再取值
if (left && up)
{
if (left==up)
{
if (i==m && j==n)
{
code[j-]=code[j]=;
dp[cur].push(encode(),dp[-cur].f[k]);
}
}
else
{
code[j-]=code[j]=;
for (int i=;i<=n;i++) if (code[i]==left) code[i]=up;
dp[cur].push(encode(),dp[-cur].f[k]);
}
} if ((left && !up) || (up && !left))
{
int t=left|up;
if (j<n)
{
code[j-]=,code[j]=t;
dp[cur].push(encode(),dp[-cur].f[k]+maze[i][j][r]);
}
if (i<m)
{
code[j-]=t,code[j]=;
dp[cur].push(encode(),dp[-cur].f[k]+maze[i][j][d]);
}
} if (!left && !up)
{
if (i<m && j<n)
{
code[j-]=code[j]=MAXN-;
dp[cur].push(encode(),dp[-cur].f[k]+maze[i][j][d]+maze[i][j][r]);
}
}
}
} void init()
{
scanf("%d%d",&m,&n);
char str[MAXN];
getchar();
gets(str);
memset(maze,0xef,sizeof(maze));
for (int i=;i<=m;i++)
{
gets(str);
for (int j=;j<=(n-);j++)
maze[i][j][r]=maze[i][j+][l]=str[*j]-'';
if (i!=m)
{
gets(str);
for (int j=;j<=n;j++)
maze[i][j][d]=maze[i+][j][u]=str[*j-]-'';
} }
gets(str);
}
void solve()
{
int cur=;
dp[cur].clear();
dp[cur].push(,);
for (int i=;i<=m;i++)
for (int j=;j<=n;j++)//m和n写反掉啦
{
cur^=;
dp[cur].clear();
dpblank(i,j,cur);
}
ll ans=1e16;
for (int i=;i<dp[cur].state.size();i++) ans=min(ans,dp[cur].f[i]);
printf("%lld\n",ans);
} int main()
{
int T;
scanf("%d",&T);
while (T--)
{
init();
solve();
}
return ;
}

[附赠:随机生成数据的程序,欢迎对拍~]

 #include<bits/stdc++.h>
using namespace std; int main()
{
freopen("test.out","w",stdout);
cout<<<<endl;
for (int t=;t<=;t++)
{
int m=rand()%+,n=rand()%+;
cout<<m<<' '<<n<<endl;
for (int i=;i<=(*n+);i++) cout<<'#';cout<<endl;
for (int i=;i<=m;i++)
{
cout<<"# ";
for (int j=;j<n;j++)
{
int x=rand()%;
cout<<x<<' ';
}
cout<<"#"<<endl;
if (i==m) break;
cout<<'#';
for (int j=;j<=n;j++)
{
int x=rand()%;
cout<<x<<'#';
}
cout<<endl;
}
for (int i=;i<=(*n+);i++) cout<<'#';cout<<endl;
}
return ;
}

【插头DP】hdu1964-Pipes的更多相关文章

  1. HDU1964 Pipes —— 插头DP

    题目链接:https://vjudge.net/problem/HDU-1964 Pipes Time Limit: 5000/1000 MS (Java/Others)    Memory Limi ...

  2. hdu1964之插头DP求最优值

    Pipes Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Subm ...

  3. 插头DP专题

    建议入门的人先看cd琦的<基于连通性状态压缩的动态规划问题>.事半功倍. 插头DP其实是比较久以前听说的一个东西,当初是水了几道水题,最近打算温习一下,顺便看下能否入门之类. 插头DP建议 ...

  4. 插头dp练习

    最近学了插头dp,准备陆续更新插头dp类练习. 学习论文还是cdq那篇<基于连通性状态压缩的动态规划问题>. 基本的想法都讲得很通透了,接下来就靠自己yy了. 还有感谢kuangbin大大 ...

  5. 插头dp

    插头dp 感受: 我觉得重点是理解,算法并不是直接想出怎样由一种方案变成另一种方案.而是方案本来就在那里,我们只是枚举状态统计了答案. 看看cdq的讲义什么的,一开始可能觉得状态很多,但其实灰常简单 ...

  6. HDU 4113 Construct the Great Wall(插头dp)

    好久没做插头dp的样子,一开始以为这题是插头,状压,插头,状压,插头,状压,插头,状压,无限对又错. 昨天看到的这题. 百度之后发现没有人发题解,hust也没,hdu也没discuss...在acm- ...

  7. HDU 4949 Light(插头dp、位运算)

    比赛的时候没看题,赛后看题觉得比赛看到应该可以敲的,敲了之后发现还真就会卡题.. 因为写完之后,无限TLE... 直到后来用位运算代替了我插头dp常用的decode.encode.shift三个函数以 ...

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

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

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

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

  10. HDU 4064 Carcassonne(插头DP)(The 36th ACM/ICPC Asia Regional Fuzhou Site —— Online Contest)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4064 Problem Description Carcassonne is a tile-based ...

随机推荐

  1. js布尔值转化

    JavaScript 预期某个位置应该是布尔值,会将该位置上现有的值自动转为布尔值.转换规则是除了下面六个值被转为false,其他值都视为true. undefined null false 0 Na ...

  2. python批量替换文件名

    替换关键字 #-*-coding:utf-8-*- import os import re filepath = u'E:\\CMMI4\\07_测试文档' files = os.walk(filep ...

  3. 144.Binary Tree Preorder Traversal---二叉树先序、中序非递归遍历

    题目链接 题目大意:返回二叉树的先序遍历list.中序见94,后序见145. 法一:普通递归遍历,只是这里多了一个list数组,所以分成了两个函数.代码如下(耗时1ms): public List&l ...

  4. Python3中字符串的编码与解码以及编码之间转换(decode、encode)

    一.编码 二.编码与解码 Python3中对py文件的默认编码是urf-8.但是字符串的编码是Unicode. 由于Unicode采用32位4个字节来表示一个字符,存储和传输太浪费资源,所以传输和存储 ...

  5. xshell 映射带跳板机服务器的端口到本地

    1.配置xshell连接跳板机服务器: 2. 3.可用navicate等同过端口连接远程数据库.

  6. 20180615 wdcp 域名解析问题

    /usr/local/nginx_bak/conf/nginx.conf  这里有个nginx的配置,修改为nginx_bak

  7. supervisor 的使用

    1.通过yum安装 supervisor: 2.supervisorctl 查看状态: 3.supervisor.d 下查看配置文件,修改命令和日志目录 4.tail -f /var/log/supe ...

  8. iOS客户端学习之AES加密

    数据加密在解密在软件开发过程中举足轻重的作用,可能有的公司在加密的时候有自己公司内部一套设计的算法,而在这方面不想浪费太大精力就可以去考虑使用第三方提供的加密算法,如AES加密算法,本篇内容介绍开源中 ...

  9. PHP 分割字串 Function 的速度比較(substr/sscanf/preg_match)---substr最快!

    固定長度的字串(假設是 06481a63041b578d702f159f520847f8), 要照固定格式做切割, 使用 PHP 要怎麼切會比較快? 註: 要將此字串切成 => 06 / 48 ...

  10. ubuntu安装Shutter截图工具以及设置系统快捷键

    一.安装截图工具 Shutter 1. 添加安装包软件源 sudo add-apt-repository ppa:shutter/ppa 2. 更新源并安装 shutter sudo apt-get ...