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;
}
posted @ 2021-02-05 20:18  WWW~~~  阅读(54)  评论(0编辑  收藏  举报