[插头dp] HDU 1693 Eat the Trees

题目链接
记录一下,不详细写了,这道题的插头只需要二进制就够了。

Code

#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <cstdio>
#include <vector>
using namespace std;

#define RG register int
#define LL long long

template<typename elemType>
inline void Read(elemType &T){
    elemType X=0,w=0; char ch=0;
    while(!isdigit(ch)) {w|=ch=='-';ch=getchar();}
    while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
    T=(w?-X:X);
}

LL dp[12][12][8200];
int G[20][20],bin[20];
int T,N,M;

LL Solve(){
    memset(dp,0,sizeof(dp));
    dp[0][M][0]=1;
    for(RG i=1;i<=N;++i){
        for(RG k=0;k<(1<<M);++k)
            dp[i][0][k<<1]=dp[i-1][M][k];
        for(RG j=1;j<=M;++j){
            for(RG k=0;k<(1<<(M+1));++k){
                int d=((k>>j)&1),r=((k>>(j-1))&1);
                if(!G[i][j]){
                    if(!d && !r) dp[i][j][k]+=dp[i][j-1][k];
                }else if((!d && !r)||(d && r))
                    dp[i][j][k^bin[j-1]^bin[j]]+=dp[i][j-1][k];
                else if((d && !r)||(!d && r)){
                    dp[i][j][k]+=dp[i][j-1][k];
                    dp[i][j][k^bin[j-1]^bin[j]]+=dp[i][j-1][k];
                }
            }
        }
    }
    return dp[N][M][0];
}

int main(){
    bin[0]=1;
    for(RG i=1;i<=13;++i)
        bin[i]=bin[i-1]<<1;
    Read(T);int Case=0;
    while(T--){
        Read(N);Read(M);
        for(RG i=1;i<=N;++i)
            for(RG j=1;j<=M;++j)
                Read(G[i][j]);
        printf("Case %d: There are %lld ways to eat the trees.\n",++Case,Solve());
    }
    return 0;
}
posted @ 2020-08-22 22:14  AE酱  阅读(97)  评论(0编辑  收藏  举报