[插头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;
}