【题目大意】

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

裸裸的插头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. 郑轻校赛 2127 tmk射气球 (数学)

    Description 有一天TMK在做一个飞艇环游世界,突然他发现有一个气球匀速沿直线飘过,tmk想起了他飞艇上有一把弓,他打算拿弓去射气球,为了提高射击的准确性,他首先在飞艇上找到一个离气球最近的 ...

  2. spring-boot 更换依赖版本

    创建Spring Boot操作步骤如下: 在File菜单里面选择 New > Project,然后选择Spring Initializr 更换版本 或 pom spring-boot-start ...

  3. tomcat和weblogic的区别

    Tomcat是Apache基金会提供的Servlet容器,它支持JSP, Servlet和JDBC等J2EE关键技术,所以用户可以用Tomcat开发基于数据库,Servlet和JSP页面的Web应用, ...

  4. Mysql储存过程4:mysql变量设置

    默认全局变量是两个@@开头, 可用show variables查看所有默认变量: @@user #declare定义变量只能用在储存过程中 #declare 变量名 数据类型 可选类型 declare ...

  5. PHP7+Nginx的配置与安装教程详解

    下面脚本之家小编把PHP7+Nginx的配置与安装教程分享给大家,供大家参考,本文写的不好还请见谅. 系统环境:centos6.5 x64 软件版本:nginx-1.10.0 php-7.0.6 安装 ...

  6. ACM International Collegiate Programming Contest World Finals 2013

    ACM International Collegiate Programming Contest World Finals 2013 A - Self-Assembly 题目描述:给出\(n\)个正方 ...

  7. 【51nod1006】simple KMP

    原题意看的挺迷糊的,后来看了http://blog.csdn.net/YxuanwKeith/article/details/52351335大爷的题意感觉清楚的多…… 做法也非常显然了,用树剖维护后 ...

  8. ../include/squid_md5.h:27:2: error: #error Cannot find OpenSSL MD5 headers【squid安装中】

    ../include/squid_md5.h:27:2: error: #error Cannot find OpenSSL MD5 headers yum install -y openssl* w ...

  9. 从LabVIEW到C++

    前言 最近一段时间一直没有更新,一方面是时间精力的问题(PS:懒癌犯了),另一方面是小黑大部分的时间都在学习C++相关知识,恶补了许多的知识(从大学C语言水平强制拔高了一段). 本文谈谈自己近期的一些 ...

  10. Nginx服务安全设置和参数调优

    1.添加参数隐藏Nginx版本号 vim /application/nginx/conf/nginx.conf #http标签下添加 server_tokens off; #测试 [root@cobb ...