ZOJ 3213

  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=15;
 23 const int HASH=10007;
 24 const int STATE=1000010;
 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=0;
 40         memset(head,-1,sizeof(head));
 41     }
 42     void push(int st,int ans)
 43     {
 44         int i,h=st%HASH;
 45         for(i=head[h];i!=-1;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[2];
 57 void decode(int *code,int m,int st)
 58 {
 59     num=st&7;//??????
 60     st>>=3;
 61     for(int i=m;i>=0;i--)
 62     {
 63         code[i]=st&7;
 64         st>>=3;
 65     }
 66 }
 67 int encode(int *code,int m)
 68 {
 69     int cnt=1;
 70     memset(ch,-1,sizeof(ch));
 71     ch[0]=0;
 72     int st=0;
 73     for(int i=0;i<=m;i++)
 74     {
 75         if(ch[code[i]]==-1)ch[code[i]]=cnt++;
 76         code[i]=ch[code[i]];
 77         st<<=3;
 78         st|=code[i];
 79     }
 80     st<<=3;
 81     st|=num;
 82     return st;
 83 }
 84 void shift(int *code,int m)
 85 {
 86     for(int i=m;i>0;i--)code[i]=code[i-1];
 87     code[0]=0;
 88 }
 89 void dpblank(int i,int j,int cur)
 90 {
 91     int k,left,up;
 92     for(k=0;k<hm[cur].size;k++)
 93     {
 94         decode(code,M,hm[cur].state[k]);
 95         left=code[j-1];
 96         up=code[j];
 97         if(left&&up)
 98         {
 99             if(left!=up)
100             {
101                 code[j-1]=code[j]=0;
102                 for(int t=0;t<=M;t++)
103                   if(code[t]==up)
104                      code[t]=left;
105                 if(j==M)shift(code,M);
106                 hm[cur^1].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+1])
115             {
116                 code[j-1]=0;
117                 code[j]=t;
118                 hm[cur^1].push(encode(code,M),hm[cur].dp[k]+maze[i][j]);
119             }
120             if(maze[i+1][j])
121             {
122                 code[j-1]=t;
123                 code[j]=0;
124                hm[cur^1].push(encode(code,j==M?M-1:M),hm[cur].dp[k]+maze[i][j]);
125             }
126             if(num<2)   //封住一端,增加一个独立插头。
127             {
128                 num++;
129                 code[j-1]=code[j]=0;
130                 hm[cur^1].push(encode(code,j==M?M-1:M),hm[cur].dp[k]+maze[i][j]);
131             }
132         }
133         else
134         {
135             code[j-1]=code[j]=0;      //讨论简单路径,只需不讨论不选的情况就可以了。
136            hm[cur^1].push(encode(code,j==M?M-1:M),hm[cur].dp[k]);   
137             if(maze[i][j+1]&&maze[i+1][j])
138             {
139                 code[j-1]=code[j]=13;
140                 hm[cur^1].push(encode(code,M),hm[cur].dp[k]+maze[i][j]);
141             }
142             if(num<2)
143             {
144                 num++;
145                 if(maze[i][j+1])
146                 {
147                     code[j]=13;
148                     code[j-1]=0;
149                     hm[cur^1].push(encode(code,M),hm[cur].dp[k]+maze[i][j]);
150                 }
151                 if(maze[i+1][j])
152                 {
153                     code[j-1]=13;
154                     code[j]=0;
155                    hm[cur^1].push(encode(code,j==M?M-1: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=0;k<hm[cur].size;k++)
165     {
166         decode(code,M,hm[cur].state[k]);//?????!!!
167         code[j-1]=code[j]=0;
168         if(j==M)shift(code,M);
169         hm[cur^1].push(encode(code,M),hm[cur].dp[k]);
170     }
171 }
172 void init()
173 {
174     scanf("%d%d",&N,&M);
175     ans=0;
176     memset(maze,0,sizeof(maze));//???????
177     for(int i=1;i<=N;i++)
178       for(int j=1;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=0;
187     hm[cur].init();
188     hm[cur].push(0,0);
189     for(i=1;i<=N;i++)
190        for(int j=1;j<=M;j++)
191        {
192            hm[cur^1].init();
193            if(maze[i][j])dpblank(i,j,cur);
194            else dpblock(i,j,cur);
195            cur^=1;
196        }
197     for(i=0;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 0;
212 }
View Code

 

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

应当初始化图为0;

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

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

 

posted @ 2014-05-28 22:41  chenjunjie1994  阅读(309)  评论(0编辑  收藏  举报