1. /*
  2. ZOJ 3213
  3.  
  4. 好吧,看过那种括号表示法后,就崩溃了,实在受不了。情况复杂,写了两天,人也有点傻X了,只能放弃,转而用最小表示法。
  5. 最小表示法不难写:
  6.  
  7. 1)首先,要承认路径上有格子不选的情况,于是,在00的情况下,可扩展,也可不选。
  8. 2)不能出现环,因而不能有L=U的情况出现。
  9. 3)以下是模版代码,类同是必然。但转而求路径数的时候,应当去掉不扩展的情况,同时,在IF(L|U)的情况下,亦不必考虑当前是否为最后一个格子,
  10. 只需按写的转移即可。
  11. 4)增加独立插头时,必须在总的独立插头数小于2的情况下进行。
  12.  
  13. 注意:之所以不能出现两个插头,是因为,独立插头是单向的路径,不能进了又出。限制这个条件是非常有必要的。而在此处我本以为若限制了条件就得不出
  14. 最优解,而其实,因为存在不选的状态,限制了这个条件依然是可以有最优解的。
  15. */
  16. #include<stdio.h>
  17. #include<string.h>
  18. #include<algorithm>
  19. #include<iostream>
  20. using namespace std;
  21.  
  22. const int MAXD=;
  23. const int HASH=;
  24. const int STATE=;
  25.  
  26. int N,M;
  27. int maze[MAXD][MAXD];
  28. int code[MAXD];
  29. int ch[MAXD];
  30. int num;
  31. int ans;
  32.  
  33. struct HASHMAP
  34. {
  35. int head[HASH],next[STATE],size;
  36. int state[STATE],dp[STATE];
  37. void init()
  38. {
  39. size=;
  40. memset(head,-,sizeof(head));
  41. }
  42. void push(int st,int ans)
  43. {
  44. int i,h=st%HASH;
  45. for(i=head[h];i!=-;i=next[i])
  46. if(state[i]==st)
  47. {
  48. if(dp[i]<ans)dp[i]=ans;
  49. return;
  50. }
  51. state[size]=st;
  52. dp[size]=ans;
  53. next[size]=head[h];
  54. head[h]=size++;
  55. }
  56. }hm[];
  57. void decode(int *code,int m,int st)
  58. {
  59. num=st&;//??????
  60. st>>=;
  61. for(int i=m;i>=;i--)
  62. {
  63. code[i]=st&;
  64. st>>=;
  65. }
  66. }
  67. int encode(int *code,int m)
  68. {
  69. int cnt=;
  70. memset(ch,-,sizeof(ch));
  71. ch[]=;
  72. int st=;
  73. for(int i=;i<=m;i++)
  74. {
  75. if(ch[code[i]]==-)ch[code[i]]=cnt++;
  76. code[i]=ch[code[i]];
  77. st<<=;
  78. st|=code[i];
  79. }
  80. st<<=;
  81. st|=num;
  82. return st;
  83. }
  84. void shift(int *code,int m)
  85. {
  86. for(int i=m;i>;i--)code[i]=code[i-];
  87. code[]=;
  88. }
  89. void dpblank(int i,int j,int cur)
  90. {
  91. int k,left,up;
  92. for(k=;k<hm[cur].size;k++)
  93. {
  94. decode(code,M,hm[cur].state[k]);
  95. left=code[j-];
  96. up=code[j];
  97. if(left&&up)
  98. {
  99. if(left!=up)
  100. {
  101. code[j-]=code[j]=;
  102. for(int t=;t<=M;t++)
  103. if(code[t]==up)
  104. code[t]=left;
  105. if(j==M)shift(code,M);
  106. hm[cur^].push(encode(code,M),hm[cur].dp[k]+maze[i][j]);
  107. }
  108. }
  109. else if(left||up)
  110. {
  111. int t;
  112. if(left)t=left;
  113. else t=up;
  114. if(maze[i][j+])
  115. {
  116. code[j-]=;
  117. code[j]=t;
  118. hm[cur^].push(encode(code,M),hm[cur].dp[k]+maze[i][j]);
  119. }
  120. if(maze[i+][j])
  121. {
  122. code[j-]=t;
  123. code[j]=;
  124. hm[cur^].push(encode(code,j==M?M-:M),hm[cur].dp[k]+maze[i][j]);
  125. }
  126. if(num<) //封住一端,增加一个独立插头。
  127. {
  128. num++;
  129. code[j-]=code[j]=;
  130. hm[cur^].push(encode(code,j==M?M-:M),hm[cur].dp[k]+maze[i][j]);
  131. }
  132. }
  133. else
  134. {
  135. code[j-]=code[j]=; //讨论简单路径,只需不讨论不选的情况就可以了。
  136. hm[cur^].push(encode(code,j==M?M-:M),hm[cur].dp[k]);
  137. if(maze[i][j+]&&maze[i+][j])
  138. {
  139. code[j-]=code[j]=;
  140. hm[cur^].push(encode(code,M),hm[cur].dp[k]+maze[i][j]);
  141. }
  142. if(num<)
  143. {
  144. num++;
  145. if(maze[i][j+])
  146. {
  147. code[j]=;
  148. code[j-]=;
  149. hm[cur^].push(encode(code,M),hm[cur].dp[k]+maze[i][j]);
  150. }
  151. if(maze[i+][j])
  152. {
  153. code[j-]=;
  154. code[j]=;
  155. hm[cur^].push(encode(code,j==M?M-:M),hm[cur].dp[k]+maze[i][j]);
  156. }
  157. }
  158. }
  159. }
  160. }
  161. void dpblock(int i,int j,int cur)
  162. {
  163. int k;
  164. for(k=;k<hm[cur].size;k++)
  165. {
  166. decode(code,M,hm[cur].state[k]);//?????!!!
  167. code[j-]=code[j]=;
  168. if(j==M)shift(code,M);
  169. hm[cur^].push(encode(code,M),hm[cur].dp[k]);
  170. }
  171. }
  172. void init()
  173. {
  174. scanf("%d%d",&N,&M);
  175. ans=;
  176. memset(maze,,sizeof(maze));//???????
  177. for(int i=;i<=N;i++)
  178. for(int j=;j<=M;j++)
  179. {
  180. scanf("%d",&maze[i][j]);
  181. if(maze[i][j]>ans)ans=maze[i][j];
  182. }
  183. }
  184. void solve()
  185. {
  186. int i,j,cur=;
  187. hm[cur].init();
  188. hm[cur].push(,);
  189. for(i=;i<=N;i++)
  190. for(int j=;j<=M;j++)
  191. {
  192. hm[cur^].init();
  193. if(maze[i][j])dpblank(i,j,cur);
  194. else dpblock(i,j,cur);
  195. cur^=;
  196. }
  197. for(i=;i<hm[cur].size;i++)
  198. if(hm[cur].dp[i]>ans)
  199. ans=hm[cur].dp[i];
  200. printf("%d\n",ans);
  201. }
  202. int main()
  203. {
  204. int T;
  205. scanf("%d",&T);
  206. while(T--)
  207. {
  208. init();
  209. solve();
  210. }
  211. return ;
  212. }

更新代码,自写的。WA了N久,感觉有几个问题要注意一下:

应当初始化图为0;

记住在增加独立插头时,任何时候要考虑是否<2

  1. #include <iostream>
  2. #include <stdio.h>
  3. #include <cstring>
  4. using namespace std;
  5.  
  6. const int MAXD=;
  7. const int MAXL=;
  8. const int MAXH=;
  9. int n,m;
  10. int ans; int num;
  11. int map[MAXD][MAXD];
  12. int code[MAXD]; int pos[MAXD],stac[MAXD];
  13. int tmp[MAXD];
  14.  
  15. struct HASHMAP{
  16. int hash[MAXL],state[MAXH],next[MAXH];
  17. int f[MAXH];
  18. int size;
  19. void init(){
  20. size=;
  21. memset(hash,-,sizeof(hash));
  22. }
  23. void push(int st,int anst) {
  24. int h=st%MAXL;
  25. for(int i=hash[h];i!=-;i=next[i]){
  26. if(state[i]==st){
  27. if(f[i]<anst){
  28. f[i]=anst;
  29. }
  30. return ;
  31. }
  32. }
  33. state[size]=st;
  34. f[size]=anst;
  35. next[size]=hash[h];
  36. hash[h]=size++;
  37. }
  38. }hm[];
  39.  
  40. void decode(int st){
  41. for(int i=m;i>=;i--){
  42. int t=st&;
  43. code[i]=t;
  44. st=st>>;
  45. }
  46. }
  47.  
  48. int fd_r(int j){
  49. int top=-;
  50. for(int i=;i<=m;i++){
  51. if(code[i]==) continue;
  52. else if(code[i]==){
  53. ++top;
  54. pos[top]=i; stac[top]=code[i];
  55. }
  56. else if(code[i]==){
  57. if(pos[top]==j) return i;
  58. else top--;
  59. }
  60. }
  61. }
  62. int fd_l(int j){
  63. int top=-;
  64. for(int i=;i<=m;i++){
  65. if(code[i]==) continue;
  66. else if(code[i]==){
  67. ++top;
  68. pos[top]=i; stac[top]=code[i];
  69. }
  70. else if(code[i]==){
  71. if(i==j) return pos[top];
  72. else top--;
  73. }
  74. }
  75. }
  76.  
  77. void dpblank(int i,int j,int cur){
  78. int em;int tmpst; int ls,us,tts;
  79. for(int e=;e<hm[cur].size;e++){
  80. int st=hm[cur].state[e];
  81. num=st&;
  82. st>>=;
  83. decode(st);
  84. int left=code[j-],up=code[j];
  85. ls=(m-j+)*; us=(m-j)*;
  86. if(!left&&!up){
  87. tmpst=(st^(left<<ls))^(up<<us);
  88. if(j==m) tmpst=tmpst>>;
  89. tmpst<<=;
  90. tmpst|=num;
  91. hm[cur^].push(tmpst,hm[cur].f[e]);
  92. if(map[i+][j]>&&map[i][j+]>){
  93. tmpst=(st^(left<<ls))^(<<ls);
  94. tmpst=(tmpst^(up<<us))^(<<us);
  95. tmpst<<=;
  96. tmpst|=num;
  97. hm[cur^].push(tmpst,hm[cur].f[e]+map[i][j]);
  98. }
  99. if(num<){
  100. num++;
  101. if(map[i][j+]>){
  102. tmpst=(st^(left<<ls));
  103. tmpst=(tmpst^(up<<us))^(<<us);
  104. tmpst<<=;
  105. tmpst|=num;
  106. hm[cur^].push(tmpst,hm[cur].f[e]+map[i][j]);
  107. }
  108. if(map[i+][j]>){
  109. tmpst=(st^(left<<ls))^(<<ls);
  110. tmpst=(tmpst^(up<<us));
  111. if(j==m) tmpst>>=;
  112. tmpst<<=;
  113. tmpst|=num;
  114. hm[cur^].push(tmpst,hm[cur].f[e]+map[i][j]);
  115. }
  116. }
  117. }
  118. else if(left&&up){
  119. if(left==&&up==){
  120. int tt=fd_r(j);
  121. tts=(m-tt)*;
  122. tmpst=(st^(code[tt]<<tts))^(<<tts);
  123. tmpst=(tmpst^(left<<ls));
  124. tmpst=(tmpst^(up<<us));
  125. tmpst<<=;
  126. tmpst|=num;
  127. hm[cur^].push(tmpst,hm[cur].f[e]+map[i][j]);
  128. }
  129. else if(left==&&up==){
  130. int tt=fd_l(j-);
  131. tts=(m-tt)*;
  132. tmpst=(st^(code[tt]<<tts))^(<<tts);
  133. tmpst=(tmpst^(left<<ls));
  134. tmpst=(tmpst^(up<<us));
  135. if(j==m) tmpst>>=;
  136. tmpst<<=;
  137. tmpst|=num;
  138. hm[cur^].push(tmpst,hm[cur].f[e]+map[i][j]);
  139. }
  140. else if(left==&&up==){
  141. tmpst=(st^(left<<ls));
  142. tmpst=(tmpst^(up<<us));
  143. if(j==m) tmpst>>=;
  144. tmpst<<=;
  145. tmpst|=num;
  146. hm[cur^].push(tmpst,hm[cur].f[e]+map[i][j]);
  147. }
  148. else if(left==&&up==){
  149. tmpst=(st^(left<<ls));
  150. tmpst=(tmpst^(up<<us));
  151. if(j==m) tmpst>>=;
  152. tmpst<<=;
  153. tmpst|=num;
  154. hm[cur^].push(tmpst,hm[cur].f[e]+map[i][j]);
  155. }
  156. else if(left==&&up!=){
  157. int tt;
  158. if(up==) tt=fd_r(j);
  159. else tt=fd_l(j);
  160. tts=(m-tt)*;
  161. tmpst=st^(left<<ls);
  162. tmpst=tmpst^(up<<us);
  163. tmpst=(tmpst^(code[tt]<<tts))^(<<tts);
  164. if(j==m) tmpst>>=;
  165. tmpst<<=;
  166. tmpst|=num;
  167. hm[cur^].push(tmpst,hm[cur].f[e]+map[i][j]);
  168. }
  169. else if(left!=&&up==){
  170. int tt;
  171. if(left==) tt=fd_r(j-);
  172. else tt=fd_l(j-);
  173. tts=(m-tt)*;
  174. tmpst=st^(left<<ls);
  175. tmpst=tmpst^(up<<us);
  176. tmpst=(tmpst^(code[tt]<<tts))^(<<tts);
  177. if(j==m) tmpst>>=;
  178. tmpst<<=;
  179. tmpst|=num;
  180. hm[cur^].push(tmpst,hm[cur].f[e]+map[i][j]);
  181. }
  182. }
  183. else{
  184. int tt,cott;
  185. if(left) tt=left;
  186. else tt=up;
  187. if(map[i][j+]>){
  188. tmpst=st^(up<<us)^(tt<<us);
  189. tmpst=tmpst^(left<<ls);
  190. tmpst<<=;
  191. tmpst|=num;
  192. hm[cur^].push(tmpst,hm[cur].f[e]+map[i][j]);
  193. }
  194. if(map[i+][j]>){
  195. tmpst=st^(left<<ls)^(tt<<ls);
  196. tmpst=tmpst^(up<<us);
  197. if(j==m) tmpst>>=;
  198. tmpst<<=;
  199. tmpst|=num;
  200. hm[cur^].push(tmpst,hm[cur].f[e]+map[i][j]);
  201. }
  202. if(tt==&&num<){ //忘了限制条件<2,WA了N久。
  203. tmpst=st^(left<<ls)^(up<<us);
  204. if(j==m) tmpst>>=;
  205. tmpst<<=;
  206. tmpst|=(num+);
  207. hm[cur^].push(tmpst,hm[cur].f[e]+map[i][j]);
  208. }
  209. if(left!=&&up!=&&num<){
  210. int sp=(tt==left? j-: j);
  211. tts=(m-sp)*;
  212. if(tt==) cott=fd_r(sp);
  213. else cott=fd_l(sp);
  214. tmpst=st^(code[sp]<<tts)^(code[cott]<<((m-cott)*))^(<<((m-cott)*));
  215. if(j==m) tmpst>>=;
  216. num++;
  217. tmpst<<=;
  218. tmpst|=num;
  219. hm[cur^].push(tmpst,hm[cur].f[e]+map[i][j]);
  220. }
  221. }
  222. }
  223. }
  224.  
  225. void dpblock(int i,int j,int cur){
  226. int em; int tmpst;
  227. for(int k=;k<hm[cur].size;k++){
  228. int st=hm[cur].state[k];
  229. num=st&;
  230. st>>=;
  231. decode(st);
  232. tmpst=st^(code[j]<<((m-j)*))^(code[j-]<<((m-j+)*));
  233. if(j==m) tmpst>>=;
  234. tmpst<<=;
  235. tmpst|=num;
  236. hm[cur^].push(tmpst,hm[cur].f[k]);
  237. }
  238. }
  239.  
  240. void solve(){
  241. int cur=,i;
  242. hm[cur].init();
  243. hm[cur].push(,);
  244. for( i=;i<=n;i++){
  245. for(int j=;j<=m;j++){
  246. hm[cur^].init();
  247. if(map[i][j]>) dpblank(i,j,cur);
  248. else dpblock(i,j,cur);
  249. cur=cur^;
  250. }
  251. }
  252. for( i=;i<hm[cur].size;i++)
  253. if(hm[cur].f[i]>ans) ans=hm[cur].f[i];
  254. printf("%d\n",ans);
  255. }
  256.  
  257. int main(){
  258. int T; int i,j;
  259. scanf("%d",&T);
  260. while(T--){
  261. ans=;
  262. scanf("%d%d",&n,&m);
  263. memset(map,,sizeof(map));
  264. for(i=;i<=n;i++){
  265. for(j=;j<=m;j++){
  266. scanf("%d",&map[i][j]);
  267. if(map[i][j]>ans) ans=map[i][j];
  268. }
  269. }
  270. solve();
  271. }
  272. return ;
  273. }

ZOJ 3213的更多相关文章

  1. ZOJ 3213 Beautiful Meadow 简单路径 插头DP

    简单路径的题目,其实就是在状态后面多记了有多少个独立插头. 分类讨论独立插头: 1.只存在上插头或者左插头,可以选择作为独立插头. 2.都不存在上插头和左插头,选择作为独立插头的同时要标号为新的连通块 ...

  2. 插头DP专题

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

  3. 插头dp的几个模板

    /* ural1519 求经过全部可行点的哈密顿回路的个数 括号匹配法,转移有点复杂,可是时间空间比較小 */ #include<cstdio> #include<cstring&g ...

  4. ZOJ People Counting

    第十三届浙江省大学生程序设计竞赛 I 题, 一道模拟题. ZOJ  3944http://www.icpc.moe/onlinejudge/showProblem.do?problemCode=394 ...

  5. ZOJ 3686 A Simple Tree Problem

    A Simple Tree Problem Time Limit: 3 Seconds      Memory Limit: 65536 KB Given a rooted tree, each no ...

  6. ZOJ Problem Set - 1394 Polar Explorer

    这道题目还是简单的,但是自己WA了好几次,总结下: 1.对输入的总结,加上上次ZOJ Problem Set - 1334 Basically Speaking ac代码及总结这道题目的总结 题目要求 ...

  7. ZOJ Problem Set - 1392 The Hardest Problem Ever

    放了一个长长的暑假,可能是这辈子最后一个这么长的暑假了吧,呵呵...今天来实验室了,先找了zoj上面简单的题目练练手直接贴代码了,不解释,就是一道简单的密文转换问题: #include <std ...

  8. ZOJ Problem Set - 1049 I Think I Need a Houseboat

    这道题目说白了是一道平面几何的数学问题,重在理解题目的意思: 题目说,弗雷德想买地盖房养老,但是土地每年会被密西西比河淹掉一部分,而且经调查是以半圆形的方式淹没的,每年淹没50平方英里,以初始水岸线为 ...

  9. ZOJ Problem Set - 1006 Do the Untwist

    今天在ZOJ上做了道很简单的题目是关于加密解密问题的,此题的关键点就在于求余的逆运算: 比如假设都是正整数 A=(B-C)%D 则 B - C = D*n + A 其中 A < D 移项 B = ...

随机推荐

  1. 开启和安装Kubernetes 基于Docker For Windows

    0.最近发现,Docker For Windows Stable在Enable Kubernetes这个问题上是有Bug的,建议切换到Edge版本,并且采用下文AliyunContainerServi ...

  2. 微信小程序图片选择,预览和删除

    这里均用的是小程序原生api 废话不多说直接上栗子: <view class="addImv"> <!--这个是已经选好的图片--> <view wx ...

  3. QT 制作串口调试小助手----(小白篇)

    一.成品图展示 简介:因zigbee实验,制作一个相对简易版的上位机,接收来自zigbee无线传感采集的温湿度.光照等数据. 并且将数据部分描绘成实时动态折线统计图. 二.主要功能介绍 主要使用QT自 ...

  4. 微信小程序调用微信支付

    1,首先我们先缕清支付的整个流程,详见https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=7_4&index=3,第一 ...

  5. 实例化flask的参数及对app的配置

    Flask 是一个非常灵活且短小精干的web框架 , 那么灵活性从什么地方体现呢? 有一个神奇的东西叫 Flask配置 , 这个东西怎么用呢? 它能给我们带来怎么样的方便呢? 首先展示一下: from ...

  6. [laravel]用户异地登录后踢掉之前的登录

    不同用户和服务器之间由一个唯一的session来区分,但是一般情况下不同的session对应的用户model可以是同一个. 为了实现只能同时在一个地方登陆,可以在用户的字段里增加一个last_sess ...

  7. SAS学习笔记之《SAS编程与数据挖掘商业案例》(5)SAS宏语言、SQL过程

    SAS学习笔记之<SAS编程与数据挖掘商业案例>(5)SAS宏语言.SQL过程 1. 一个SAS程序可能包含一个或几个语言成分: DATA步或PROC步 全程语句 SAS组件语言(SCL) ...

  8. Android文件操作报open failed: EBUSY (Device or resource busy)

    Android删除文件后重新创建时偶尔出现 open failed: EBUSY (Device or resource busy)错误,该错误是Android系统的一个bug,大概的意思类似于win ...

  9. Git的使用及托管代码到GitHub

    首先Git是一个开源的分布式版本控制工具,用git创建代码仓库. 仓库(Repository)是用于保存版本管理所需信息的地方,本地代码 提交到 代码仓库中,如果需要还可以 再推送到 远程仓库中. 所 ...

  10. sql server 大数据跨服务器迁移表数据——使用链接服务器

    1.创建链接服务器(填写链接服务器.远程登录.使用密码) 2.188.188.1.177是远程的 select count(*) from [188.188.1.177].BigDataAnalysi ...