[Explanations] cornfield

Like pressure Series II.

Topic Link

Title effect: Given a \ (n * m \) matrix, which can put some of the position, some can not. The provisions of a grid put the left and right can not put it down. Asked to put the program how many grid.

Considering the \ (n, m \) is small, as is the shape of the pressure.

Consider pressure-like representation, we put each line \ (01 \) matrix pressed into binary, it indicates the status of the line.

So after we finished pressure line, apparently \ (n \) number indicates the status of each line. That is the total number of states \ (the n-2 ^ \) .

Also, because it can not be put right and left, then first such legal status to handle it.

Continue to be considered \ (dp \) a.

Through each row (compressed state), for each state to enumerate what it may correspond to the status and the status of its next line may correspond. We can put in front of your experiences with legitimate programs Boolean arrays.

So we must first choose a legitimate state. Secondly, this state can not be given a map of the area planted in the title. We can use \ (j & mp [i] == j \) to determine whether or not legal.

So then enumerate the next line state. Obviously up and down two rows can not have adjacent \ (1 \) , \ (J & k \) can be.

Then that is loved by the cumulative state.

Topic done. Note that the left and right judgment, they can:

$ i&(i<<1)==0 $ \(&&\) \(i&(i>>1)==0\)

Note priority, habits parentheses.

\(Code:\)

#include<iostream>
using namespace std;
int n,m,a[20][20],mp[20];
int dp[20][5000],Ans;
bool state[5000];
const int Hws=100000000;
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;++i)
        for(int j=1;j<=m;++j)
            scanf("%d",&a[i][j]);
    for(int i=1;i<=n;++i)
        for(int j=1;j<=m;++j)
            mp[i]=(mp[i]<<1)+a[i][j];
    for(int i=0;i<(1<<m);++i)if(((i&(i<<1))==0)&&((i&(i>>1)))==0)state[i]=1;
    dp[0][0]=1;
    for(int i=1;i<=n;++i){
        for(int j=0;j<(1<<m);++j)
            if(state[j]&&((j&mp[i])==j)){
                for(int k=0;k<(1<<m);++k)
                    if((k&j)==0){
                        dp[i][j]+=dp[i-1][k];
                        dp[i][j]%=Hws;
                    }
            }
    }
    for(int i=0;i<(1<<m);++i)Ans+=dp[n][i],Ans%=Hws;
    printf("%d\n",Ans);
    return 0;
}

Guess you like

Origin www.cnblogs.com/h-lka/p/11402173.html