POJ-3133 Manhattan Wiring 插头DP

  题目链接:http://poj.org/problem?id=3133

  用两条线段分别连接2-2和3-3,使得他们长度的总和最小。

  典型的插头DP题目,用0,2,3,种状态来表示每个格子的插头分别是没有插头,2号插头,3号插头,然后把所有可能的转移情况列出来,只是情况比较多,而且一定要考虑仔细,不然检查代码会很惨的。。话说A完这道题后感觉真爽啊O(∩_∩)O~

  1 //STATUS:C++_AC_360MS_900KB

  2 #include<stdio.h>

  3 #include<stdlib.h>

  4 #include<string.h>

  5 #include<math.h>

  6 #include<iostream>

  7 #include<string>

  8 #include<algorithm>

  9 #include<vector>

 10 #include<queue>

 11 #include<stack>

 12 #include<map>

 13 using namespace std;

 14 #define LL long long

 15 #define pii pair<int,int>

 16 #define Max(a,b) ((a)>(b)?(a):(b))

 17 #define Min(a,b) ((a)<(b)?(a):(b))

 18 #define mem(a,b) memset(a,b,sizeof(a))

 19 #define lson l,mid,rt<<1

 20 #define rson mid+1,r,rt<<1|1

 21 const int N=10,INF=0x3f3f3f3f,MOD=60007,STA=1000010;

 22 const LL LNF=0x3f3f3f3f3f3f3f3f;

 23 const double DNF=100000000000;

 24 

 25 int g[N][N];

 26 int n,m;

 27 

 28 struct Hash{

 29     int first[MOD],next[STA],size;

 30     int f[STA],sta[STA];

 31     void init(){

 32         size=0;

 33         mem(first,-1);

 34     }

 35     void add(int st,int ans){

 36         int i,u=st%MOD;

 37         for(i=first[u];i!=-1;i=next[i]){

 38             if(sta[i]==st){

 39                 f[i]=Min(f[i],ans);

 40                 return;

 41             }

 42         }

 43         f[size]=ans;

 44         sta[size]=st;

 45         next[size]=first[u];

 46         first[u]=size++;

 47     }

 48 }hs[2];

 49 

 50 void shift(int p)

 51 {

 52     int i,flag=(1<<((m+1)<<1))-1;

 53     for(i=0;i<hs[!p].size;i++){

 54         hs[p].add((hs[!p].sta[i]<<2)&flag,hs[!p].f[i]);

 55     }

 56 }

 57 

 58 int slove()

 59 {

 60     int i,j,k,x,y,left,up,p,sta,f;

 61     hs[0].init();

 62     hs[0].add(0,0);

 63     hs[p=1].init();

 64     for(i=0;i<n;i++){

 65         for(j=0;j<m;j++,hs[p=!p].init()){

 66             for(k=0;k<hs[!p].size;k++){

 67                 sta=hs[!p].sta[k];

 68                 f=hs[!p].f[k]+1;

 69                 x=(3<<(j<<1))&sta;

 70                 y=(3<<((j+1)<<1))&sta;

 71                 left=x>>(j<<1);

 72                 up=y>>((j+1)<<1);

 73                 if(g[i][j]){

 74                     if(g[i][j]==2){  //独立插头

 75                         if(left==2 && up==0){

 76                             hs[p].add(sta^x,f);

 77                         }

 78                         else if(left==0 && up==2){

 79                             hs[p].add(sta^y,f);

 80                         }

 81                         else if(left==0 && up==0){

 82                             if(g[i+1][j]==1 || g[i+1][j]==2)hs[p].add(sta|(2<<(j<<1)),f);

 83                             if(g[i][j+1]==1 || g[i][j+1]==2)hs[p].add(sta|(2<<((j+1)<<1)),f);

 84                         }

 85                     }

 86                     else if(g[i][j]==3){  //独立插头

 87                         if(left==3 && up==0){

 88                             hs[p].add(sta^x,f);

 89                         }

 90                         else if(left==0 && up==3){

 91                             hs[p].add(sta^y,f);

 92                         }

 93                         else if(left==0 && up==0){

 94                             if(g[i+1][j]==1 || g[i+1][j]==3)hs[p].add(sta|(3<<(j<<1)),f);

 95                             if(g[i][j+1]==1 || g[i][j+1]==3)hs[p].add(sta|(3<<((j+1)<<1)),f);

 96                         }

 97                     }

 98                     else {  //g[i][j]==1

 99                         if(left==up && left){

100                             hs[p].add(sta^x^y,f);

101                         }

102                         else if((left==2 && up==0) || (left==0 && up==2)){

103                             if(g[i+1][j])hs[p].add(sta^y|(2<<(j<<1)),f);

104                             if(g[i][j+1])hs[p].add(sta^x|(2<<((j+1)<<1)),f);

105                         }

106                         else if((left==3 && up==0) || (left==0 && up==3)){

107                             if(g[i+1][j])hs[p].add(sta^y|(3<<(j<<1)),f);

108                             if(g[i][j+1])hs[p].add(sta^x|(3<<((j+1)<<1)),f);

109                         }

110                         else if(left==0 && up==0){   //这里一定要考虑仔细

111                             if(g[i+1][j] && g[i][j+1]){

112                                 hs[p].add(sta|(2<<(j<<1))|(2<<((j+1)<<1)),f);

113                                 hs[p].add(sta|(3<<(j<<1))|(3<<((j+1)<<1)),f);

114                             }

115                             hs[p].add(sta,f-1);

116                         }

117                     }

118                 }

119                 else if(left==0 && up==0){

120                     hs[p].add(sta,f-1);

121                 }

122             }

123         }

124         shift(p);

125         hs[p=!p].init();

126     }

127     p=!p;

128     for(i=0;i<hs[p].size;i++){

129         if(hs[p].sta[i]==0)return hs[p].f[i]-2;

130     }

131     return 0;

132 }

133 

134 int main()

135 {

136  //   freopen("in.txt","r",stdin);

137     int i,j,ans;

138     while(~scanf("%d%d",&n,&m) && (n || m))

139     {

140         mem(g,0);

141         for(i=0;i<n;i++){

142             for(j=0;j<m;j++){

143                 scanf("%d",&g[i][j]);

144                 if(g[i][j]==0)g[i][j]=1;

145                 else if(g[i][j]==1)g[i][j]=0;

146             }

147         }

148 

149         ans=slove();

150 

151         printf("%d\n",ans);

152     }

153     return 0;

154 }

 

你可能感兴趣的:(poj)