poj1038 Bugs Integrated, Inc.[状压DP]

Tiling changed my understanding of the issues. First, according to previous understanding, to represent the line of the current situation of laying, noting that due to the vertically placed bricks is three layers, so to save the state of the two lines, that is, for $ a [i] [j] and a [i -1] [j] $ laying state.

1. How to design state

Nothing but four cases.

  • $ S_ {i, j} = s {i-1, j} = 0 $, no two cells plated. $ 0 $ express available
  • $ S_ {i, j} = 0, s {i-1, j} = 1 $, $ a $ 1 represents
  • $ S_ {i, j} = 1, s {i-1, j} = 0 $, and below that this case can be combined, as long as the time after dp row is $ I $ $ $ 1, on the top line is valid not control, and with $ 2 $ express
  • $ S_ {i, j} = s {i-1, j} = 1 $, supra

After three kinds are combined, it may then be Yingkang ternary, set $ f_i, S $ most when laying the first row state $ I $ $ $ S, so that it can be pushed up.

2. How dp

In fact, you can enumerate the current layer, then a layer of enumeration, and then determine the legality of the transfer, but this belongs to the violence enumeration (what you do with artillery method) , a large number of invalid state is enumerated. Contour DP may be employed to reduce the enumeration, but is said to be T, not tried.

Here in order to ensure only legitimate state into the next level from the current state, using DFS to DP, ie after layer on $ S $ enumeration, calculate the next layer initial state (that is, if someone is on the floor there $ $ 2, $ next layer should be $ 1, and so on), and then finish the paving on the basis of the initial enumeration active state, while updating answer.

This method can solve many basic tiling problem. It can also be transformed into statistical programs and so on.

time complexity? Theory $ O (n3 ^ {2m}) $, but the actual second $ O (3 ^ n) $ simply run dissatisfaction, may be just a constant level, it is particularly fast metaphysical.

Details

  • Why must ternary? If the two binary numbers with plug DP class representation, convenient enumeration? You may also be written, thought.
  • Inactive represented by -1, skip directly enumeration.
  • Ternary split, note-bit computing
  • Scroll array, and pulled clear to -1 after enumeration.
  • RE * 1: line42's now forget forget. .
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 #define dbg(x) cerr << #x << " = " << x <<endl
 7 using namespace std;
 8 typedef long long ll;
 9 typedef double db;
10 typedef pair<int,int> pii;
11 template<typename T>inline T _min(T A,T B){return A<B?A:B;}
12 template<typename T>inline T _max(T A,T B){return A>B?A:B;}
13 template<typename T>inline char MIN(T&A,T B){return A>B?(A=B,1):0;}
14 template<typename T>inline char MAX(T&A,T B){return A<B?(A=B,1):0;}
15 template<typename T>inline void _swap(T&A,T&B){A^=B^=A^=B;}
16 template<typename T>inline T read(T&x){
17     x=0;int f=0;char c;while(!isdigit(c=getchar()))if(c=='-')f=1;
18     while(isdigit(c))x=x*10+(c&15),c=getchar();return f?x=-x:x;
19 }
20 const int N=150+3,M=10+3;
21 const int bin[]={1,3,9,27,81,243,729,2187,6561,19683,59049};
22 int bad[N][M],now[M],pre[M];
23 int f[2][59050];//59050=3^10
24 int T,n,m,k,d,ans;
25 void dp(int j,int sum,int cur){
26     MAX(f[d^1][cur],sum);
27     if(j>=m)return;
28     if(!now[j]&&!now[j+1]&&!pre[j]&&!pre[j+1])dp(j+2,sum+1,cur+2*(bin[j-1]+bin[j]));//
29     if(j<m-1&&!now[j]&&!now[j+1]&&!now[j+2])dp(j+3,sum+1,cur+2*(bin[j-1]+bin[j]+bin[j+1]));//
30     dp(j+1,sum,cur);
31 }
32 
33 int main(){//freopen("test.in","r",stdin);//freopen("test.ans","w",stdout);
34     read(T);while(T--){
35         read(n),read(m),read(k);
36         memset(f,-1,sizeof f),memset(bad,0,sizeof bad),ans=0;
37         for(register int i=1,x,y;i<=k;++i)read(x),read(y),bad[x][y]=1;
38         f[d=0][bin[m]-1]=0;
39         for(register int i=1;i<=n;++i,d^=1){
40             for(register int s=0,cur=0;s<bin[m];++s,cur=0)if(~f[d][s]){
41                 for(register int j=1;j<=m;++j)
42                     if(bad[i][j])cur+=2*bin[j-1],now[j]=2;
43                     else cur+=bin[j-1]*(now[j]=_max((pre[j]=s/bin[j-1]%3)-1,0));
44                 dp(1,f[d][s],cur);f[d][s]=-1;
45             }
46         }
47         for(register int i=0;i<bin[m];++i)MAX(ans,f[d][i]);
48         printf("%d\n",ans);
49     }
50     return 0;
51 }
View Code

There are a fairy with binary written, by my worship. . .

Guess you like

Origin www.cnblogs.com/saigyouji-yuyuko/p/11543585.html