【HDOJ】【1964】Pipes

插头DP



  做完Formula 1以后这就是傻逼题了……直接将“数路径方案数”改为“计算路径长度取最小值”即可,没多大难度

  都不用判当前格子是否能够到达的……不过!外边的一圈“墙”还是要加的!不然会有冗余状态……会TLE

  比较蛋疼的是地图的读入……不过好好思考一下还是可以写出来的= =(sigh……花了半小时)

调了一上午的原因?……

  两个左插头的时候要向右找,遇到左插头计数器+1,遇到右插头计数器-1。

  而两个右插头的时候向左找,过程刚好相反……但我写反了啊!!!仍旧是左+右-了……so sad……傻逼错误毁一生啊!

  1 //HDU 1964
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<cstdlib>
  5 #include<iostream>
  6 #include<algorithm>
  7 #define rep(i,n) for(int i=0;i<n;++i)
  8 #define F(i,j,n) for(int i=j;i<=n;++i)
  9 #define D(i,j,n) for(int i=j;i>=n;--i)
 10 #define CC(a,b) memset(a,b,sizeof(a))
 11 using namespace std;
 12 //#define debug
 13 typedef unsigned long long u64;
 14 typedef long long LL;
 15 const int M=100007,INF=100000000;
 16 u64 mp[15][15][2];
 17 int n,m,k;
 18 int tot[2],bit[15],hash[M],state[2][M];
 19 u64 dp[2][M],ans;
 20
 21 void init(){
 22     F(i,0,14) F(j,0,14) F(k,0,1) mp[i][j][k]=INF;
 23     CC(dp,0);
 24     tot[0]=1,k=0,ans=INF;
 25     state[0][1]=dp[0][1]=0;
 26     char ch;
 27     char s[100];
 28     scanf("%d%d%*c",&n,&m);
 29     gets(s);
 30     F(i,1,(n<<1)-1){
 31         gets(s);//读一整行,含换行符
 32         if (i&1){
 33             F(j,1,m-1<<1)
 34                 if ((j&1)==0) mp[(i>>1)+1][j>>1][0]=s[j]-‘0‘;
 35         }
 36         else{
 37             int temp=1;
 38             F(j,1,m){
 39                 mp[i>>1][j][1]=s[temp]-‘0‘;
 40                 temp+=2;
 41             }
 42         }
 43     }
 44     scanf("%s\n",s);
 45 }
 46 inline void hash_in(int s,u64 sum){
 47     int p=s%M;
 48     while(hash[p]){
 49         if (state[k][hash[p]]==s){
 50             dp[k][hash[p]]=min(dp[k][hash[p]],sum);
 51             return;
 52         }
 53         p++;
 54         if (p==M) p=0;
 55     }
 56     hash[p]=++tot[k];
 57     state[k][hash[p]]=s;
 58     dp[k][hash[p]]=sum;
 59 }
 60 #define in hash_in(s,sum)
 61 void work(){
 62     F(i,1,n){
 63         F(j,1,m){
 64             k^=1;
 65             tot[k]=0;
 66             CC(hash,0);
 67             F(u,1,tot[1-k]){
 68                 int s=state[1-k][u];
 69                 u64 sum=dp[1-k][u];
 70                 int p=(s>>bit[j-1])&3,q=(s>>bit[j])&3;
 71                 if (!p && !q){
 72                     s=s^(1<<bit[j-1])^(1<<bit[j]<<1);
 73                     hash_in(s,sum+mp[i][j][0]+mp[i][j][1]);
 74                 }else if(!p && q){
 75                     hash_in(s,sum+mp[i][j][0]);
 76                     s=s^q*(1<<bit[j-1])^q*(1<<bit[j]);
 77                     hash_in(s,sum+mp[i][j][1]);
 78                 }else if(p && !q){
 79                     hash_in(s,sum+mp[i][j][1]);
 80                     s=s^p*(1<<bit[j-1])^p*(1<<bit[j]);
 81                     hash_in(s,sum+mp[i][j][0]);
 82                 }else if(p+q==2){
 83                     int nd=1;
 84                     F(u,j+1,m){
 85                         int w=(s>>bit[u])&3;
 86                         if (w==1) nd++;
 87                         if (w==2) nd--;
 88                         if (!nd) {s-=(1<<bit[u]); break;}
 89                     }
 90                     s=s^(1<<bit[j])^(1<<bit[j-1]);hash_in(s,sum);
 91                 }else if(p+q==4){
 92                     int nd=1;
 93                     D(u,j-2,1){
 94                         int w=(s>>bit[u])&3;
 95                         if (w==2) nd++;
 96                         if (w==1) nd--;
 97                         if (!nd) {s+=(1<<bit[u]); break;}
 98                     }
 99                     s=s^(1<<bit[j]<<1)^(1<<bit[j-1]<<1);hash_in(s,sum);
100                 }else if(p==1 && q==2){
101                     if (i==n && j==m) ans=min(sum,ans);
102                 }else if(p==2 && q==1) s=s^(1<<bit[j-1]<<1)^(1<<bit[j]),in;
103             }
104         }
105         F(j,1,tot[k]) state[k][j]<<=2;
106     }
107     printf("%llu\n",ans);
108 }
109 int main(){
110     F(i,0,14) bit[i]=i<<1;
111     int T;
112     scanf("%d",&T);
113     while(T--){
114         init();
115         work();
116     }
117     return 0;
118 }

时间: 2024-10-31 09:17:52

【HDOJ】【1964】Pipes的相关文章

【HDOJ图论题集】【转】

1 =============================以下是最小生成树+并查集====================================== 2 [HDU] 3 1213 How Many Tables 基础并查集★ 4 1272 小希的迷宫 基础并查集★ 5 1325&&poj1308 Is It A Tree? 基础并查集★ 6 1856 More is better 基础并查集★ 7 1102 Constructing Roads 基础最小生成树★ 8 1232

【HDOJ】1198 Farm Irrigation

其实就是并查集,写麻烦了,同样的代码第一次提交wa了,第二次就过了. 1 #include <stdio.h> 2 #include <string.h> 3 4 #define MAXNUM 55 5 #define UP 0 6 #define RIGHT 1 7 #define DOWN 2 8 #define LEFT 3 9 10 char buf[MAXNUM][MAXNUM]; 11 int bin[MAXNUM*MAXNUM]; 12 char visit[MAXN

【HDOJ】4956 Poor Hanamichi

基本数学题一道,看错位数,当成大数减做了,而且还把方向看反了.所求为最接近l的值. 1 #include <cstdio> 2 3 int f(__int64 x) { 4 int i, sum; 5 6 i = sum = 0; 7 while (x) { 8 if (i & 1) 9 sum -= x%10; 10 else 11 sum += x%10; 12 ++i; 13 x/=10; 14 } 15 return sum; 16 } 17 18 int main() { 1

【HDOJ】1099 Lottery

题意超难懂,实则一道概率论的题目.求P(n).P(n) = n*(1+1/2+1/3+1/4+...+1/n).结果如果可以除尽则表示为整数,否则表示为假分数. 1 #include <cstdio> 2 #include <cstring> 3 4 #define MAXN 25 5 6 __int64 buf[MAXN]; 7 8 __int64 gcd(__int64 a, __int64 b) { 9 if (b == 0) return a; 10 else return

【HDOJ】2844 Coins

完全背包. 1 #include <stdio.h> 2 #include <string.h> 3 4 int a[105], c[105]; 5 int n, m; 6 int dp[100005]; 7 8 int mymax(int a, int b) { 9 return a>b ? a:b; 10 } 11 12 void CompletePack(int c) { 13 int i; 14 15 for (i=c; i<=m; ++i) 16 dp[i]

【HDOJ】3509 Buge&#39;s Fibonacci Number Problem

快速矩阵幂,系数矩阵由多个二项分布组成.第1列是(0,(a+b)^k)第2列是(0,(a+b)^(k-1),0)第3列是(0,(a+b)^(k-2),0,0)以此类推. 1 /* 3509 */ 2 #include <iostream> 3 #include <string> 4 #include <map> 5 #include <queue> 6 #include <set> 7 #include <stack> 8 #incl

【HDOJ 4763】 Theme Section (KMP+strstr)

[HDOJ 4763] Theme Section Theme Section Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1999    Accepted Submission(s): 947 Problem Description It's time for music! A lot of popular musicians a

【HDOJ 4768】 Flyer (等差数列+二分)

[HDOJ 4768] Flyer (等差数列+二分) Flyer Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2022    Accepted Submission(s): 743 Problem Description The new semester begins! Different kinds of student soc

【HDOJ 5379】 Mahjong tree

[HDOJ 5379] Mahjong tree 往一颗树上标号 要求同一父亲节点的节点们标号连续 同一子树的节点们标号连续 问一共有几种标法 画了一画 发现标号有二叉树的感觉 初始标号1~n 根结点1可以标1或n 否则其他情况无法让下面的子树满足各自连续并且该根的儿子节点都要连续 根结点下的节点平分其他标号 画一画可以发现 每个根下最多有两颗子树 否则无法满足条件 并且两颗子树占据剩余标号的左右两边 中间夹的必须是叶子 这样才能满足该根下的儿子节点标号连续 若根下只有一颗子树 同样可以选择占剩

【HDOJ】1818 It&#39;s not a Bug, It&#39;s a Feature!

状态压缩+优先级bfs. 1 /* 1818 */ 2 #include <iostream> 3 #include <queue> 4 #include <cstdio> 5 #include <cstring> 6 #include <cstdlib> 7 #include <algorithm> 8 using namespace std; 9 10 #define MAXM 105 11 12 typedef struct {