标签:c style class blog code tar
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 }
标签:c style class blog code tar
原文地址:http://www.cnblogs.com/jie-dcai/p/3758040.html