【题目大意】

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

裸裸的插头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. ES6核心,值得驻足花一天时间来学习

    1.let 和 const 命令 在es5时,只有两种变量声明,var 和function.在es6中新增了四种let和const,以及另外两种声明import和class. 我们先讲解let和con ...

  2. 如何关闭sublime更新提示

    前提:sublime已激活

  3. phinx:php数据库迁移

    Phinx使你的php app进行数据迁移的过程变得异常轻松,在五分钟之内你就可以安装好Phinx 并进行数据迁移. 特性 使用php代码进行数据迁移 部署模式下迁移 五分钟之内使用 不再担心数据库的 ...

  4. 64_p6

    polkit-kde-5.10.1-1.fc26.x86_64.rpm 12-Jun-2017 13:45 84854 polkit-libs-0.113-8.fc26.i686.rpm 13-Apr ...

  5. React 16 源码瞎几把解读 【前戏】 为啥组件外面非得包个标签?

    〇.看前准备 1.自行clone react最新代码 2.自行搭建一个能跑react的test项目 一.看表面:那些插件 如何解析JSX 有如下一段代码: // ---- hearder.jsx 组件 ...

  6. mac 上使用octave的plot错误的解决办法

    在mac10.10上使用octave的时候,键入 plot(x, y)的时候会出现如下错误: ^ line : unknown or ambiguous terminal type; type jus ...

  7. 大数据系列之kafka-java实现

    Java源码GitBub地址: https://github.com/fzmeng/kafka-demo 关于kafka安装步骤可见文章   http://www.cnblogs.com/cnmeng ...

  8. 【BubbleCup X】G:Bathroom terminal

    一个hash的题 对?出现位置直接暴力枚举,然后hash判断下,扔进map里 cf的评测机跑的针tm块 #include<bits/stdc++.h> ; ; typedef long l ...

  9. spring-mybatis.xml配置

    1.自动扫描 <context:component-scan base-package="com.javen" /> 2.引入配置文件 <bean id=&quo ...

  10. 自动ftp 上传

    #!/bin/sh ftp -n<<END_FTP open 192.168.1.4 user codfei duibuqi //用户名codfei 密码duibuqi binary pr ...