bzoj 1087 (как дп давления)

портал

Значение вопросов:

Дайте вам \ (п * п \) сетку, если первая \ (я \) квадраты в часть, восемь направлений Юник пешка не может быть помещена, спросите помещенный \ (к \) несколько частей программы.

Анализ:

Очевидно , можно \ (дп \) , и потому , что \ (п \) очень мало, поэтому мы можем констатировать , метод сжатия , используемый. Set \ (дп [я] [состояние ] [к] \) для текущего раздела \ (I \) строка состояния для \ (State \) при размещении \ (K \) число частей программы.

Текущее состояние г-го ряда, может по- видимому , с первого \ (я-1 \) в строке состояния переведен из, а потому , что вы хотите встретиться с China Unicom не может иметь восемь штук, поэтому мы , как давление \ (State [двутавровых] \) , и \ (состояние [J] \) , до тех пор , как удовлетворяющие \ (Государственный [I] , \ & (Государственный [I] <<. 1) \) , \ (Государственный [J] , \ & (Государственный [Дж] <<. 1) \) , \ (State [I] \ & (State [J] <<. 1) \) , \ (State [I] \ & (State [J] >>. 1) \) , \ (State [I] \ & состояние [J] \) больше , чем \ (0 \) может. Наконец , есть уравнение перехода состояний: \ (ДП [I] , [состояние [I]] [ 'бит (Государственный [I]) + K] + = DP [I - 1.] [' Бит (Государственный [Дж])] [K] \ )

Суммарная сложность времени: \ (\ mathcal {O} (2 ^ {N-2} * К *) \)

Код:

#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;
}

рекомендация

отwww.cnblogs.com/Chen-Jr/p/11289702.html