【题目大意】

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

裸裸的插头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. How to reset XiaoMi bluetooth headphone Youth edition.

    To reset the speaker 1. Long press the phone call button to shut off the speaker 2. Connect the char ...

  2. 原创:HTML 头像截取上传 JS+PHP 整合包~

    关于: 关于头像上传这个东西,网上一搜乱七八糟的一堆然而很少很少有自己中意的插件一怒之下就自己写一个... 用法: <!DOCTYPE html> <html lang=" ...

  3. POJ 3233 Matrix Power Series (矩阵快速幂)

    题目链接 Description Given a n × n matrix A and a positive integer k, find the sum S = A + A^2 + A^3 + - ...

  4. Verilog笔记.5.同步、异步

    在数字电路中经常有同步synchronism.异步asynchronism的概念.异步指输入信号和时钟无关:同步指输入信号和时钟信号有关,实际上就是输入信号和时钟信号进行了与运算或者与非运算.实际开发 ...

  5. 01布尔模型&倒排索引

    原文链接: http://www.cnblogs.com/jacklu/p/8379726.html 博士一年级选了这门课 SEEM 5680 Text Mining Models and Appli ...

  6. $FFT$(快速傅里叶变换)

    - 概念引入 - 点值表示 对于一个$n - 1$次多项式$A(x)$,可以通过确定$n$个点与值(即$x$和$y$)来表示这唯一的$A(x)$ - 复数 对于一元二次方程 $$x^2 + 1 = 0 ...

  7. html---规范、细节积累-01

    语义错误 块级元素可以包含内联元素和某些块级元素,内联元素不能包含块级元素,只能包含内联元素 页面可能正常解析,但不符合语义.浏览器自带容错机制,对于不规范的写法也能够正确解析,各浏览器的容错机制不同 ...

  8. windows下phpstrom中xdebug的使用

    https://laravel-china.org/articles/16425/windows-phpstorm-xdebug-breakpoint-debugging

  9. python开发web服务器——搭建简易网站

    参看:https://blog.csdn.net/baidu_35085676/article/details/69807145

  10. NSBundle pathForResource is NULL 取不到值

    错误提示: Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSURL i ...