zoukankan      html  css  js  c++  java
  • 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
    ",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
    ",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
  • 相关阅读:
    YAOI Summer Round #4 (Div.2) 题解
    2021 暑假集训(福建师大附中)
    YAOI Round #7 题解
    YAOI Round #5 题解
    插头DP
    四边形不等式
    YAOI Round #3 题解
    关于 2020 年
    图论相关性质和结论(基础)
    斜率优化 DP :Luogu P2365 P5785「SDOI2012」任务安排 & 弱化版
  • 原文地址:https://www.cnblogs.com/jie-dcai/p/3758040.html
Copyright © 2011-2022 走看看