插头DP小结
首先是CDQ《基于连通性状态压缩的动态规划问题》论文上的题目:
URAL 1519 Formula
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 const int maxn = 15; 6 const int HASH = 30007; 7 const int SIZE = 1000010; 8 typedef long long LL; 9 int N,M,maze[maxn][maxn],code[maxn],ch[maxn],ex,ey; 10 char b[maxn]; 11 12 struct Hashmap{ 13 int e,first[HASH],next[SIZE]; 14 LL state[SIZE],f[SIZE]; 15 16 void init(){ 17 e = 0; 18 memset(first,-1,sizeof(first)); 19 } 20 21 void push(LL st,LL ans){ 22 int h = st%HASH; 23 for(int i = first[h];i != -1;i = next[i]) 24 if(state[i] == st){ 25 f[i] += ans; 26 return; 27 } 28 state[e] = st; 29 f[e] = ans; 30 next[e] = first[h]; 31 first[h] = e++; 32 } 33 }dp[2]; 34 35 void update(int *code,int len){ 36 for(int i = len;i >= 1;i--) 37 code[i] = code[i-1]; 38 code[0] = 0; 39 } 40 41 void decode(int *code,int len,LL st){ 42 for(int i = len;i >= 0;i--){ 43 code[i] = st&7; 44 st >>= 3; 45 } 46 } 47 48 LL encode(int *code,int len){ 49 int cnt = 1; 50 memset(ch,-1,sizeof(ch)); 51 ch[0] = 0; 52 LL st = 0; 53 for(int i = 0;i <= len;i++){ 54 if(ch[code[i]] == -1){ 55 ch[code[i]] = cnt++; 56 } 57 code[i] = ch[code[i]]; 58 st <<= 3; 59 st |= code[i]; 60 } 61 return st; 62 } 63 64 void dpblank(int i,int j,int now,int pre){ 65 int left,up,t; 66 for(int k = 0;k < dp[pre].e;k++){ 67 decode(code,M,dp[pre].state[k]); 68 left = code[j-1],up = code[j]; 69 70 if(left && up){ 71 if(left == up){ 72 if(i == ex && j == ey){ 73 code[j-1] = code[j] = 0; 74 if(j == M) update(code,M); 75 dp[now].push(encode(code,M),dp[pre].f[k]); 76 } 77 } 78 else{ 79 code[j-1] = code[j] = 0; 80 for(t = 0;t <= M;t++){ 81 if(code[t] == up) code[t] = left; 82 } 83 if(j == M) update(code,M); 84 dp[now].push(encode(code,M),dp[pre].f[k]); 85 } 86 }else if((!left && up) ||(left && !up)){ 87 if(left) t = left; 88 else t = up; 89 if(maze[i][j+1]){ 90 code[j-1] = 0,code[j] = t; 91 dp[now].push(encode(code,M),dp[pre].f[k]); 92 } 93 if(maze[i+1][j]){ 94 code[j-1] = t,code[j] = 0; 95 if(j == M) update(code,M); 96 dp[now].push(encode(code,M),dp[pre].f[k]); 97 } 98 }else{ 99 if(maze[i+1][j] && maze[i][j+1]){ 100 code[j-1] = code[j] = 13; 101 dp[now].push(encode(code,M),dp[pre].f[k]); 102 } 103 } 104 } 105 } 106 107 void dpblock(int i,int j,int now,int pre){ 108 for(int k = 0;k < dp[pre].e;k++){ 109 decode(code,M,dp[pre].state[k]); 110 code[j-1] = code[j] = 0; 111 if(j == M) update(code,M); 112 dp[now].push(encode(code,M),dp[pre].f[k]); 113 } 114 } 115 116 int main() 117 { 118 while(scanf("%d%d",&N,&M) != EOF){ 119 memset(maze,0,sizeof(maze)); 120 ex = 0; 121 for(int i = 1;i <= N;i++){ 122 scanf("%s",b+1); 123 for(int j = 1;j <= M;j++) 124 if(b[j] == '.') maze[ex=i][ey=j] = 1; 125 } 126 if(ex == 0){ 127 printf("0\n"); 128 continue; 129 } 130 int now = 0,pre = 1; 131 dp[now].init(); 132 dp[now].push(0,1); 133 for(int i = 1;i <= N;i++){ 134 for(int j = 1;j <= M;j++){ 135 swap(now,pre); 136 dp[now].init(); 137 if(maze[i][j]) dpblank(i,j,now,pre); 138 else dpblock(i,j,now,pre); 139 } 140 } 141 LL ans = 0; 142 for(int i = 0;i < dp[now].e;i++) 143 ans += dp[now].f[i]; 144 printf("%I64d\n",ans); 145 } 146 return 0; 147 }
POJ 1739 Tony's Tour
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 const int maxn = 15; 6 const int HASH = 30007; 7 const int SIZE = 1000010; 8 typedef long long LL; 9 int N,M,maze[maxn][maxn],code[maxn],ch[maxn],ex,ey; 10 char b[maxn]; 11 12 struct Hashmap{ 13 int e,first[HASH],next[SIZE]; 14 LL state[SIZE],f[SIZE]; 15 16 void init(){ 17 e = 0; 18 memset(first,-1,sizeof(first)); 19 } 20 21 void push(LL st,LL ans){ 22 int h = st%HASH; 23 for(int i = first[h];i != -1;i = next[i]) 24 if(state[i] == st){ 25 f[i] += ans; 26 return; 27 } 28 state[e] = st; 29 f[e] = ans; 30 next[e] = first[h]; 31 first[h] = e++; 32 } 33 }dp[2]; 34 35 void update(int *code,int len){ 36 for(int i = len;i >= 1;i--) 37 code[i] = code[i-1]; 38 code[0] = 0; 39 } 40 41 void decode(int *code,int len,LL st){ 42 for(int i = len;i >= 0;i--){ 43 code[i] = st&7; 44 st >>= 3; 45 } 46 } 47 48 LL encode(int *code,int len){ 49 int cnt = 1; 50 memset(ch,-1,sizeof(ch)); 51 ch[0] = 0; 52 LL st = 0; 53 for(int i = 0;i <= len;i++){ 54 if(ch[code[i]] == -1){ 55 ch[code[i]] = cnt++; 56 } 57 code[i] = ch[code[i]]; 58 st <<= 3; 59 st |= code[i]; 60 } 61 return st; 62 } 63 64 void dpblank(int i,int j,int now,int pre){ 65 int left,up,t; 66 for(int k = 0;k < dp[pre].e;k++){ 67 decode(code,M,dp[pre].state[k]); 68 left = code[j-1],up = code[j]; 69 70 if(left && up){ 71 if(left == up){ 72 if(i == ex && j == ey){ 73 code[j-1] = code[j] = 0; 74 if(j == M) update(code,M); 75 dp[now].push(encode(code,M),dp[pre].f[k]); 76 } 77 } 78 else{ 79 code[j-1] = code[j] = 0; 80 for(t = 0;t <= M;t++){ 81 if(code[t] == up) code[t] = left; 82 } 83 if(j == M) update(code,M); 84 dp[now].push(encode(code,M),dp[pre].f[k]); 85 } 86 }else if((!left && up) ||(left && !up)){ 87 if(left) t = left; 88 else t = up; 89 if(maze[i][j+1]){ 90 code[j-1] = 0,code[j] = t; 91 dp[now].push(encode(code,M),dp[pre].f[k]); 92 } 93 if(maze[i+1][j]){ 94 code[j-1] = t,code[j] = 0; 95 if(j == M) update(code,M); 96 dp[now].push(encode(code,M),dp[pre].f[k]); 97 } 98 }else{ 99 if(maze[i+1][j] && maze[i][j+1]){ 100 code[j-1] = code[j] = 13; 101 dp[now].push(encode(code,M),dp[pre].f[k]); 102 } 103 } 104 } 105 } 106 107 void dpblock(int i,int j,int now,int pre){ 108 for(int k = 0;k < dp[pre].e;k++){ 109 decode(code,M,dp[pre].state[k]); 110 code[j-1] = code[j] = 0; 111 if(j == M) update(code,M); 112 dp[now].push(encode(code,M),dp[pre].f[k]); 113 } 114 } 115 116 int main() 117 { 118 while(scanf("%d%d",&N,&M),N+M){ 119 memset(maze,0,sizeof(maze)); 120 for(int i = 1;i <= N;i++){ 121 scanf("%s",b+1); 122 for(int j = 1;j <= M;j++) 123 if(b[j] == '.') maze[i][j] = 1; 124 } 125 maze[N+1][1] = maze[N+1][M] = 1; 126 for(int i = 2;i < M;i++) maze[N+1][i] = 0; 127 for(int i = 1;i <= M;i++) maze[N+2][i] = 1; 128 N += 2; 129 ex = N,ey = M; 130 131 int now = 0,pre = 1; 132 dp[now].init(); 133 dp[now].push(0,1); 134 for(int i = 1;i <= N;i++){ 135 for(int j = 1;j <= M;j++){ 136 swap(now,pre); 137 dp[now].init(); 138 if(maze[i][j]) dpblank(i,j,now,pre); 139 else dpblock(i,j,now,pre); 140 } 141 } 142 LL ans = 0; 143 for(int i = 0;i < dp[now].e;i++) 144 ans += dp[now].f[i]; 145 printf("%I64d\n",ans); 146 } 147 return 0; 148 }
UVA 10572 Black and White
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 const int HASH = 10007; 6 const int SIZE = 10000; 7 int N,M; 8 char maze[10][10]; 9 int pre[65][SIZE],opt[65][SIZE]; 10 11 struct Hashmap{ 12 int e,first[HASH],next[SIZE]; 13 int color[SIZE],state[SIZE],f[SIZE]; 14 15 void init(){ 16 e = 0; 17 memset(first,-1,sizeof(first)); 18 } 19 20 void push(int st,int col,int ans,int id,int k,char ch){ 21 int h = ((st<<6)+col) % HASH; 22 for(int i = first[h];i != -1;i = next[i]) 23 if(state[i] == st && color[i] == col){ 24 f[i] += ans; 25 return; 26 } 27 state[e] = st; 28 color[e] = col; 29 f[e] = ans; 30 pre[id][e] = k; 31 opt[id][e] = ch; 32 next[e] = first[h]; 33 first[h] = e++; 34 } 35 }dp[2]; 36 37 int code[10],ch[10]; 38 39 void decode(int *code,int len,int st){ 40 for(int i = len-1;i >= 0;i--){ 41 code[i] = st&7; 42 st >>= 3; 43 } 44 } 45 46 int encode(int *code,int len){ 47 int st = 0,cnt = 0; 48 memset(ch,-1,sizeof(ch)); 49 for(int i = 0;i < len;i++){ 50 if(ch[code[i]] == -1) 51 ch[code[i]] = cnt++; 52 st = st<<3|ch[code[i]]; 53 } 54 return st; 55 } 56 57 void DP(int i,int j,int c,int now,int pre){ 58 for(int k = 0;k < dp[pre].e;k++){ 59 int col = dp[pre].color[k]; 60 int up = i ? ((col>>j)&1)==c : 0; 61 int left = j ? (col>>(j-1)&1)==c : 0; 62 int lu = (col>>M)== c; 63 if(up && left && lu) continue; 64 if(i == N-1 && j == M-1 && !up && !left && lu) continue; 65 decode(code,M,dp[pre].state[k]); 66 if(i && !up){ 67 int s1 = 0,s2 = 0; 68 for(int t = 0;t < M;t++){ 69 if(code[t] == code[j]) s1++; 70 if(((col>>t)&1) != c) s2++; 71 } 72 if(s1 == 1){ 73 if(s2 > 1) continue; 74 if(i < N-1 || j < M-2) continue; 75 } 76 } 77 if(up && left){ 78 if(code[j] != code[j-1]){ 79 for(int t = 0,x = code[j];t < M;t++) 80 if(code[t] == x) code[t] = code[j-1]; 81 } 82 } 83 else if(!up && left) code[j] = code[j-1]; 84 else if(!up && !left) code[j] = M; 85 86 if(col&(1<<j)) col |= (1<<M); 87 else col &= ~(1<<M); 88 if(c) col |= (1<<j); 89 else col &= ~(1<<j); 90 dp[now].push(encode(code,M),col,dp[pre].f[k],i*M+j,k,c ? '#' : 'o'); 91 } 92 } 93 94 void print(int k){ 95 for(int i = N-1;i >= 0;i--) 96 for(int j = M-1;j >= 0;j--) 97 maze[i][j] = opt[i*M+j][k],k = pre[i*M+j][k]; 98 for(int i = 0;i < N;i++) puts(maze[i]); 99 } 100 101 int main(){ 102 //freopen("input.txt","r",stdin); 103 int kase; 104 scanf("%d",&kase); 105 while(kase--){ 106 scanf("%d%d",&N,&M); 107 for(int i = 0;i < N;i++) 108 scanf("%s",maze[i]); 109 int now = 0,pre = 1; 110 int ans = 0; 111 dp[now].init(); 112 dp[now].push(0,0,1,0,0,0); 113 for(int i = 0;i < N;i++) 114 for(int j = 0;j < M;j++){ 115 now ^= 1,pre ^= 1; 116 dp[now].init(); 117 if(maze[i][j] != '#') DP(i,j,0,now,pre); 118 if(maze[i][j] != 'o') DP(i,j,1,now,pre); 119 } 120 121 int k; 122 for(int i = 0;i < dp[now].e;i++){ 123 int tmp = 0; 124 decode(code,M,dp[now].state[i]); 125 for(int j = 0;j < M;j++) 126 tmp = max(tmp,code[j]); 127 if(tmp > 1) continue; 128 ans += dp[now].f[i],k = i; 129 } 130 printf("%d\n",ans); 131 if(ans != 0) print(k); 132 } 133 return 0; 134 }
HYSBZ 1494 生成树计数
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 const int N = 1<<6; 7 const int MOD = 65521; 8 int K,tot_status,f[N],fa[10]; 9 int status[N],ord[1<<16]; 10 long long n; 11 struct Matrix{ 12 long long mat[N][N]; 13 Matrix operator*(const Matrix m)const{ 14 Matrix tmp; 15 for(int i = 0;i < tot_status;i++){ 16 for(int j = 0;j < tot_status;j++){ 17 tmp.mat[i][j] = 0; 18 for(int k = 0;k < tot_status;k++){ 19 tmp.mat[i][j] += mat[i][k]*m.mat[k][j]%MOD; 20 tmp.mat[i][j] %= MOD; 21 } 22 } 23 } 24 return tmp; 25 } 26 }; 27 28 long long Pow(Matrix &m,long long n){ 29 Matrix ans; 30 memset(ans.mat,0,sizeof(ans.mat)); 31 for(int i = 0;i < tot_status;i++) 32 ans.mat[i][i] = 1; 33 n -= K; 34 while(n){ 35 if(n&1) ans = ans*m; 36 n >>= 1; 37 m = m*m; 38 } 39 long long sum = 0; 40 for(int i = 0;i < tot_status;i++){ 41 sum += ans.mat[0][i]*f[i]; 42 sum %= MOD; 43 } 44 return sum; 45 } 46 47 bool check(int st){ 48 int tmp = 0; 49 for(int i = 0;i < K;i++){ 50 int tp = (st>>(i*3))&7;tmp |= (1<<tp); 51 for(int j = 1;j <= tp;j++) if(!(tmp&(1<<j))) return 0; 52 } 53 return 1; 54 } 55 56 void dfs(int dep,int st){ 57 if(dep == K){ 58 if(check(st)) ord[st] = tot_status,status[tot_status++] = st; 59 return; 60 } 61 for(int i = 1;i <= K;i++) dfs(dep+1,st|(i<<(3*dep))); 62 } 63 64 int find(int x){ 65 return fa[x] == x ? x : fa[x] = find(fa[x]); 66 } 67 68 int main() 69 { 70 //freopen("output.txt","w",stdout); 71 scanf("%d%lld",&K,&n); 72 tot_status = 0; 73 dfs(1,1); 74 Matrix m; 75 memset(m.mat,0,sizeof(m.mat)); 76 for(int i = 0;i < tot_status;i++){ 77 f[i] = 1; 78 int cnt[10]; 79 memset(cnt,0,sizeof(cnt)); 80 for(int j = 0;j < K;j++) 81 cnt[status[i]>>(j*3)&7]++; 82 for(int j = 1;j <= K;j++){ 83 if(cnt[j] == 3) f[i] = 3; 84 if(cnt[j] == 4) f[i] = 16; 85 if(cnt[j] == 5) f[i] = 125; 86 } 87 for(int s = 0;s < (1<<K);s++){ 88 for(int j = 0;j <= K;j++) fa[j] = j; 89 for(int j = 0;j < K;j++){ 90 for(int k = j+1;k < K;k++) 91 if(((status[i]>>(j*3))&7) == ((status[i]>>(k*3))&7)) 92 fa[find(j)] = find(k); 93 } 94 bool flag = 1; 95 for(int j = 0;j < K;j++)if(s&(1<<j)){ 96 if(find(j) == find(K)){flag = 0;break;} 97 else fa[find(j)] = find(K); 98 } 99 if(!flag) continue; 100 flag = 0; 101 for(int j = 1;j <= K;j++) 102 if(find(0) == find(j)){flag = 1;break;} 103 if(!flag) continue; 104 int use = 0,nxt = 0; 105 for(int j = 0;j < K;j++)if(!(nxt&(7<<(j*3)))){ 106 nxt |= ++use<<(j*3); 107 for(int k = j+1;k < K;k++) 108 if(find(j+1) == find(k+1)) nxt |= use<<(k*3); 109 } 110 m.mat[ord[nxt]][i]++; 111 } 112 } 113 printf("%lld\n",Pow(m,n)); 114 return 0; 115 }
ZOJ 2125 Rocket Mania
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #define get(x,t) (((x) >> (t)) & 1) 5 #define get2(x,t) (((x) >> (t<<2)) &15) 6 const int HASH = 30007; 7 const int SIZE = 100000; 8 const int maxn = 10; 9 typedef long long LL; 10 struct Node{ 11 int s1; 12 LL s2; 13 }; 14 char map[maxn][maxn]; 15 int code[maxn],ch[maxn]; 16 Node best; 17 int last,n; 18 struct Hashmap{ 19 int e,first[HASH],next[SIZE]; 20 Node node[SIZE]; 21 22 void init(){ 23 e = 0; 24 memset(first,-1,sizeof(first)); 25 } 26 27 void push(int s1,LL s2){ 28 int h = abs(s1*s2+s1+s2) % HASH; 29 for(int i = first[h];i != -1;i = next[i]) 30 if(node[i].s1 == s1 && node[i].s2 == s2) 31 return; 32 node[e].s1 = s1,node[e].s2 = s2; 33 next[e] = first[h]; 34 first[h] = e++; 35 } 36 }dp[2]; 37 38 void decode(int *code,LL st){ 39 for(int i = 0;i <= 9;i++,st >>= 4) 40 code[i] = st&15; 41 } 42 43 LL encode(int *code){ 44 LL st = 0; 45 int cnt = 1; 46 memset(ch,-1,sizeof(ch)); 47 for(int i = 9;i >= 0;i--){ 48 if(code[i] && ch[code[i]] == -1) 49 ch[code[i]] = cnt++; 50 if(code[i]) code[i] = ch[code[i]]; 51 st = st<<4; 52 st |= code[i]; 53 } 54 return st; 55 } 56 57 void update(int *code){ 58 for(int i = 9;i >= 1;i--) 59 code[i] = code[i-1]; 60 code[0] = 0; 61 } 62 63 int merge(int fire,int a,int b){ 64 int t = get(fire,a)|get(fire,b); 65 a = code[a],b = code[b]; 66 for(int i = 0;i <= 9;i++) 67 if(code[i] == b) code[i] = a; 68 for(int i = 0;i <= 9;i++) 69 if(code[i] == a) fire |= (t<<i); 70 return fire; 71 } 72 73 Node check(Node t){ 74 for(int i = 0;i <= 9;i++) 75 if(get2(t.s2,i) && !get(t.s1,i)){ 76 bool flag = 1; 77 for(int j = 0;j <= 9;j++) 78 if(i != j && get2(t.s2,i) == get2(t.s2,j)){ 79 flag = 0; 80 break; 81 } 82 if(flag) t.s2 ^= (get2(t.s2,i)<<(i<<2)); 83 } 84 return t; 85 } 86 87 void insert(int s1,LL s2,int now){ 88 if(!s1) return; 89 bool flag = 1; 90 for(int i = 0;i <= 9;i++) 91 if(get2(s2,i) && !get(best.s1,i)){ 92 flag = 0;break; 93 } 94 if(flag) return; 95 int tmp1 = 0,tmp2 = 0; 96 for(int i = 0;i <= 9;i++) 97 tmp1 += get(s1,i),tmp2 += get(best.s1,i); 98 if(tmp1 > tmp2) best.s1 = s1,best.s2 = s2; 99 if(last != -1){ 100 for(int i = 0;i <= last;i++) 101 if(!get(s1,i) && get2(s2,i)){ 102 flag = 1; 103 for(int t = last+1;t <= 9;t++) 104 if(get2(s2,i) == get2(s2,t)){ 105 flag = 0;break; 106 } 107 if(flag) s2 ^= (get2(s2,i)<<(i<<2)); 108 } 109 decode(code,s2),s2 = encode(code); 110 } 111 dp[now].push(s1,s2); 112 } 113 114 int DP(){ 115 int t = 1<<n-1; 116 code[9] = 0; 117 for(int i = 0;i < 9;i++){ 118 if(get(t,i)) code[i] = 1; 119 else code[i] = 0; 120 } 121 best.s1 = 0,best.s2 = 0; 122 int now = 0,pre = 1; 123 dp[now].init(); 124 insert(t,encode(code),now); 125 last = -1; 126 for(int j = -1;j < 6;j++){ 127 for(int i = j == -1 ? 8 : 0;i < 9;i++){ 128 now ^= 1,pre ^= 1; 129 dp[now].init(); 130 best.s1 = best.s2 = 0; 131 132 for(int k = 0;k < dp[pre].e;k++){ 133 Node t = dp[pre].node[k]; 134 t = check(t); 135 decode(code,t.s2); 136 if(i == 0){ 137 update(code); 138 t.s2 = encode(code); 139 int tmp = get(t.s1,9); 140 t.s1 ^= (tmp << 9); 141 t.s1 <<= 1; 142 } 143 int up = code[i],left = code[i+1]; 144 int a1 = get(t.s1,i),a2 = get(t.s1,i+1); 145 last = (j == 5 ? i : -1); 146 147 if(map[i][j] == '.'){ 148 decode(code,t.s2); 149 code[i] = code[i+1] = 0; 150 insert(t.s1^(a1<<i)^(a2<<i+1),encode(code),now); 151 }else if(map[i][j] == 'L'){ 152 decode(code,t.s2); 153 code[i] = code[i+1] = 9; 154 insert(t.s1^(a1<<i)^(a2<<i+1),encode(code),now); 155 if(up){ 156 decode(code,t.s2); 157 code[i+1] = 0; 158 insert(t.s1^(a2<<i+1),encode(code),now); 159 } 160 if(left){ 161 decode(code,t.s2); 162 code[i] = 0; 163 insert(t.s1^(a1<<i),encode(code),now); 164 } 165 if(left && up){ 166 decode(code,t.s2); 167 int fire = merge(t.s1,i,i+1); 168 int p = a1|a2; 169 code[i] = code[i+1] = 0; 170 insert(fire^(p<<i)^(p<<i+1),encode(code),now); 171 } 172 }else if(map[i][j] == '-'){ 173 if(!left&&!up){ 174 decode(code,t.s2); 175 code[i] = code[i+1] = 0; 176 insert(t.s1^(a1<<i)^(a2<<i+1),encode(code),now); 177 } 178 if(up){ 179 decode(code,t.s2); 180 code[i+1] = code[i],code[i] = 0; 181 insert(t.s1^(a1<<i)^(a2<<i+1)^(a1<<i+1),encode(code),now); 182 } 183 if(left){ 184 decode(code,t.s2); 185 code[i] = code[i+1],code[i+1] = 0; 186 insert(t.s1^(a1<<i)^(a2<<i+1)^(a2<<i),encode(code),now); 187 } 188 }else if(map[i][j] == 'T'){ 189 if(up){ 190 decode(code,t.s2); 191 code[i+1] = code[i]; 192 insert(t.s1^(a2<<i+1)^(a1<<i+1),encode(code),now); 193 }else{ 194 decode(code,t.s2); 195 code[i] = code[i+1] = 9; 196 insert(t.s1^(a1<<i)^(a2<<i+1),encode(code),now); 197 } 198 if(left){ 199 decode(code,t.s2); 200 code[i] = code[i+1]; 201 insert(t.s1^(a1<<i)^(a2<<i),encode(code),now); 202 }else{ 203 decode(code,t.s2); 204 code[i] = code[i+1] = 9; 205 insert(t.s1^(a1<<i)^(a2<<i+1),encode(code),now); 206 } 207 if(up && left){ 208 decode(code,t.s2); 209 int fire = merge(t.s1,i,i+1); 210 int p = a1|a2; 211 code[i] = 0; 212 insert(fire^(p<<i),encode(code),now); 213 }else if(up){ 214 decode(code,t.s2); 215 code[i+1] = code[i],code[i] = 0; 216 insert(t.s1^(a1<<i)^(a2<<i+1)^(a1<<i+1),encode(code),now); 217 }else if(left){ 218 decode(code,t.s2); 219 code[i] = 0; 220 insert(t.s1^(a1<<i),encode(code),now); 221 } 222 if(up && left){ 223 decode(code,t.s2); 224 int fire = merge(t.s1,i,i+1); 225 int p = a1|a2; 226 code[i+1] = 0; 227 insert(fire^(p<<i+1),encode(code),now); 228 }else if(up){ 229 decode(code,t.s2); 230 code[i+1] = 0; 231 insert(t.s1^(a2<<i+1),encode(code),now); 232 }else if(left){ 233 decode(code,t.s2); 234 code[i] = code[i+1],code[i+1] = 0; 235 insert(t.s1^(a1<<i)^(a2<<i+1)^(a2<<i),encode(code),now); 236 } 237 }else{ 238 if(up && left){ 239 decode(code,t.s2); 240 int fire = merge(t.s1,i,i+1); 241 insert(fire,encode(code),now); 242 }else if(up){ 243 decode(code,t.s2); 244 code[i+1] = code[i]; 245 insert(t.s1^(a1<<i+1),encode(code),now); 246 }else if(left){ 247 decode(code,t.s2); 248 code[i] = code[i+1]; 249 insert(t.s1^(a2<<i),encode(code),now); 250 }else{ 251 decode(code,t.s2); 252 code[i+1] = code[i] = 9; 253 insert(t.s1^(a1<<i)^(a2<<i+1),encode(code),now); 254 } 255 } 256 } 257 } 258 } 259 260 int ans = 0; 261 for(int k = 0;k < dp[now].e;k++){ 262 Node t = dp[now].node[k]; 263 int tmp = 0; 264 for(int i = 0;i < 9;i++) 265 tmp += get(t.s1,i); 266 ans = tmp > ans ? tmp : ans; 267 } 268 printf("%d\n",ans); 269 } 270 271 int main () 272 { 273 while(scanf("%d",&n) != EOF){ 274 for(int i = 0;i < 9;i++) 275 scanf("%s",map[i]); 276 DP(); 277 } 278 return 0 ; 279 }