Topic Link: http://poj.org/problem?id=3254
Q: Give a n row of grass, 1 for fertile, 0 for barren, now to put some cows on the fertile grass, but ask all cows can not adjacent, ask you how many kinds of method.
Analysis: If we know all the things that can be put in the i-1 line, so for the first row of a situation, we just judge it and the i-1 row of all the circumstances can not meet the problem of all cows are not adjacent, if the kind of satisfaction, then for the I row of the case there is an X-way.
The previous analysis shows that satisfying the sub state, we are sure we can use DP to solve.
But we also found that the state is a method of release, not our usual DP of the simple state, so to use state compression.
But what is state compression?
For example, in front of the case, a method of release is up to 12 0 or 1 of the composition, then we can easily think of the binary, using a binary number to represent a method of release.
Defines the status DP "I" "J", and the number of cattle grazing when line I is State J. J Words we convert to binary, from low to high order 1 means cattle 0 means no cattle, can represent a row of all the situation.
Then the transfer equation DP "I" "J" =sum (dp "I-1" "K")
The key of state compression DP is to deal with the good bit operation.
This problem uses the & operator.
Use X & (X<<1) to determine whether a number of adjacent two digits is also 1, if 1 then return a value, otherwise return 0, so you can optimize the state
Use the Boolean value of X & Y to determine whether the same is the same as 1.
Code:
#include <cstdio> #include <cstring> const int N = 13;
const int M = 1<<n;
const int mod = 100000000; int st[m],map[m]; The state of each row and the state int dp[n][m of the given place are respectively stored;
Represents the number of species that can be used to herd cattle when the state of line I is J bool Judge1 (int x)//To determine whether the binary has adjacent 1 {return (x& (x<<1)); bool Judge2 (int i,int x) {
Return (Map[i]&st[x]);
int main () {int n,m,x;
while (~SCANF ("%d%d", &n,&m)) {memset (st,0,sizeof (ST));
memset (map,0,sizeof (map));
Memset (Dp,0,sizeof (DP));
for (int i=1;i<=n;i++) {for (int j=1;j<=m;j++) {scanf ("%d", &x);
if (x==0) map[i]+= (1<< (j-1));
} int k=0;
for (int i=0;i< (1<<m); i++) {if (!judge1 (i)) st[k++]=i;
for (int i=0;i<k;i++) {if (!judge2 (1,i)) dp[1][i]=1;
for (int i=2;i<=n;i++) { for (int j=0;j<k;j++) {if (Judge2 (I,J))//To Judge line I if I were to herd by State J.
Continue
for (int f=0;f<k;f++) {if (Judge2 (i-1,f))//pruning determines whether the previous line and its state are satisfied
Continue if (!) (
ST[J]&ST[F]) dp[i][j]+=dp[i-1][f];
{}} int ans=0;
for (int i=0;i<k;i++) {ans+=dp[n][i];
Ans%=mod;
printf ("%d\n", ans);
return 0;
}