bzoj 1087 (like pressure dp)

Portal

Meaning of the questions:

Give you a \ (n * n \) grid, if the first \ (i \) squares into the piece, the eight directions Unicom pawn can not be placed, ask placed \ (k \) several pieces of the program.

analysis:

Obviously can \ (dp \) , and because \ (n \) is very small, so we can state the compression method used. Set \ (dp [i] [state ] [k] \) for the current section \ (I \) status line for \ (State \) when placed \ (K \) number of pieces of the program.

The current state of the i-th row, can apparently from the first \ (i-1 \) status line transferred from, but because you want to meet China Unicom can not have eight pieces, so we like pressure \ (State [the I] \) , and \ (state [j] \) , as long as satisfying \ (State [I] \ & (State [I] <<. 1) \) , \ (State [J] \ & (State [J] <<. 1) \) , \ (State [I] \ & (State [J] <<. 1) \) , \ (State [I] \ & (State [J] >>. 1) \) , \ (State [the I] \ & state [j] \) greater than \ (0 \) can. Finally there is a state transition equation: \ (DP [I] [State [I]] [ 'bit (State [I]) + K] + = DP [the I-. 1] [' bit (State [J])] [K] \ )

The total time complexity is: \ (\ mathcal {O} (2 ^ {n-2} * K *) \)

Code:

#include <bits/stdc++.h>
#define maxn 10
using namespace std;
long long dp[maxn][1<<maxn][maxn*maxn];
int getbit(int x){
    int res=0;
    while(x){
        if(x&1) res++;
        x>>=1;
    }
    return res;
}
int main()
{
    int n,k;
    memset(dp,0,sizeof(dp));
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++){
        int all=1<<n;
        for(int j=0;j<all;j++){
            if(j&(j<<1)) continue;
            if(i==1){
                if(getbit(j)<=k) dp[i][j][getbit(j)]++;
                continue;
            }
            for(int kk=0;kk<all;kk++){
                if(kk&(kk<<1)) continue;
                if((j&kk)||(j&(kk<<1))||(j&(kk>>1))) continue;
                for(int ll=0;ll<=k;ll++){
                    dp[i][j][getbit(j)+ll]+=dp[i-1][kk][ll];
                }
            }
        }
    }
    long long res=0;
    int all=1<<n;
    for(int i=0;i<all;i++){
        res+=dp[n][i][k];
    }
    printf("%lld\n",res);
    return 0;
}

Guess you like

Origin www.cnblogs.com/Chen-Jr/p/11289702.html