poj 2411 动态规划 状态压缩

题意:用1*2的矩形,覆盖m*n的大矩形,问有多少种情况。

 

 

long long dp[30][1<<12],b[30][1<<12],width,height;   //用int出错
long long solve(int i,int j,int pos,int state){    //第i行初始状态为j
    if(b[i][state])return dp[i][state];
    if(pos==width){
        if(i<=height){
            int s=~j&((1<<width)-1);
            dp[i][state]+=solve(i+1,s,0,s);
        }
        return 0;
    }
    solve(i,j,pos+1,state);//第pos列不放
    if(pos<=width-2&&!(j&1<<pos)&&!(j&1<<(pos+1)))//还有两列没放,并且没因上一行没放而必须竖放
        solve(i,j|1<<pos|1<<(pos+1),pos+2,state);//横放
    if(!pos)b[i][state]=1;
    return dp[i][state];
}
int main(){
    while(cin>>height>>width,height){
        memset(b,0,sizeof(b));
        memset(dp,0,sizeof(dp));
        dp[height+1][0]=1;
        cout<<solve(1,0,0,0)<<endl;
    }
    return 0;
}

/*
long long dp[30][1<<12],width,height,cnt;   
void solve(int i,int j,int pos){    //第i行初始状态为j,有cnt种方法
    if(pos==width){dp[i][j]+=cnt;return;}   //第i行放完,终态j的情况+cnt
    solve(i,j,pos+1);//第pos列不放
    if(pos<=width-2&&!(j&1<<pos)&&!(j&1<<(pos+1)))//还有两列没放,并且没因上一行没放而必须竖放
        solve(i,j|1<<pos|1<<(pos+1),pos+2);//横放
}
int main(){
    while(cin>>height>>width,height){
        memset(dp,0,sizeof(dp));cnt=1;
        solve(1,0,0);
        for(int i=2;i<=height;i++)
            for(int j=0;j<1<<width;j++)
                if(dp[i-1][j]){
                    cnt=dp[i-1][j];
                    solve(i,~j&((1<<width)-1),0);
                }
        cout<<dp[height][(1<<width)-1]<<endl;
    }
    return 0;
}*/

 

posted @ 2013-06-19 14:13  心向往之  阅读(214)  评论(0编辑  收藏  举报