插头DP
做完Formula 1以后这就是傻逼题了……直接将“数路径方案数”改为“计算路径长度取最小值”即可,没多大难度
都不用判当前格子是否能够到达的……不过!外边的一圈“墙”还是要加的!不然会有冗余状态……会TLE(如果是有障碍物的题的话直接就WA了,@楼教主的Tonys Tour)
比较蛋疼的是地图的读入……不过好好思考一下还是可以写出来的= =(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 ",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 ",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 }