Eat the Trees 题解
Eat the Trees 题解
Eat the Trees - HDU 1693 - Virtual Judge (vjudge.net)
这次不是口胡了。。
插头dp就好了。
画出几个case:
/*
{
######################
# Author #
# Gary #
# 2021 #
######################
*/
#include<bits/stdc++.h>
#define rb(a,b,c) for(int a=b;a<=c;++a)
#define rl(a,b,c) for(int a=b;a>=c;--a)
#define LL long long
#define IT iterator
#define PB push_back
#define II(a,b) make_pair(a,b)
#define FIR first
#define SEC second
#define FREO freopen("check.out","w",stdout)
#define rep(a,b) for(int a=0;a<b;++a)
#define SRAND mt19937 rng(chrono::steady_clock::now().time_since_epoch().count())
#define random(a) rng()%a
#define ALL(a) a.begin(),a.end()
#define POB pop_back
#define ff fflush(stdout)
#define fastio ios::sync_with_stdio(false)
#define check_min(a,b) a=min(a,b)
#define check_max(a,b) a=max(a,b)
using namespace std;
//inline int read(){
// int x=0;
// char ch=getchar();
// while(ch<'0'||ch>'9'){
// ch=getchar();
// }
// while(ch>='0'&&ch<='9'){
// x=(x<<1)+(x<<3)+(ch^48);
// ch=getchar();
// }
// return x;
//}
const int INF=0x3f3f3f3f;
typedef pair<int,int> mp;
/*}
*/
int n,m;
LL dp[13][12][1<<12];
int a[12][12];
int get(int num,int pos){
return (num>>(pos-1))&1;
}
void solve(int test){
scanf("%d%d",&n,&m);
rb(i,1,n) rb(j,1,m) scanf("%d",&a[i][j]);
int all=(1<<(m+1))-1;
memset(dp,0,sizeof(dp));
dp[1][1][0]=1;
rb(i,1,n) rb(j,1,m){
rep(mask,1<<(m+1)){
if(j!=m){
if(get(mask,j)&&get(mask,j+1)){
int nmask=mask^(1<<(j-1))^(1<<j);
if(a[i][j])dp[i][j+1][nmask]+=dp[i][j][mask];
}
if(get(mask,j)&&!get(mask,j+1)){
int nmask=mask^(1<<(j-1));
if(a[i][j]){
dp[i][j+1][nmask|(1<<j)]+=dp[i][j][mask];
dp[i][j+1][nmask|(1<<(j-1))]+=dp[i][j][mask];
}
}
if(!get(mask,j)&&get(mask,j+1)){
int nmask=mask^(1<<(j));
if(a[i][j]){
dp[i][j+1][nmask|(1<<j)]+=dp[i][j][mask];
dp[i][j+1][nmask|(1<<(j-1))]+=dp[i][j][mask];
}
}
if(!get(mask,j)&&!get(mask,j+1)){
if(a[i][j]){
dp[i][j+1][mask|(1<<j)|(1<<(j-1))]+=dp[i][j][mask];
}
else
dp[i][j+1][mask]+=dp[i][j][mask];
}
}
else{
if(get(mask,j)&&get(mask,j+1)){
int nmask=mask^(1<<(j-1))^(1<<j);
nmask<<=1;
nmask&=all;
if(a[i][j])dp[i+1][1][nmask]+=dp[i][j][mask];
}
if(get(mask,j)&&!get(mask,j+1)){
int nmask=mask^(1<<(j-1));
nmask|=1<<(j-1);
nmask<<=1;
nmask&=all;
if(a[i][j]){
dp[i+1][1][nmask]+=dp[i][j][mask];
}
}
if(!get(mask,j)&&get(mask,j+1)){
int nmask=mask^(1<<(j));
nmask|=(1<<(j-1));
nmask<<=1;
nmask&=all;
if(a[i][j]){
dp[i+1][1][nmask]+=dp[i][j][mask];
}
}
if(!get(mask,j)&&!get(mask,j+1)){
if(!a[i][j]) dp[i+1][1][(mask<<1)&all]+=dp[i][j][mask];
}
}
}
}
printf("Case %d: There are %lld ways to eat the trees.\n",test,dp[n+1][1][0]);
}
int main(){
int T;
scanf("%d",&T);
int id=0;
while(T--) solve(++id);
return 0;
}