poj1321

这题深搜不会啊,就会状压dp,好久没敲代码了,有些要注意的地方都忘了,dp要注意不要出现多余情况,恩。。。就是。。。就像背包一样某些物品智能装一个,就要从后向前一面装多了,我这题就碰到这种问题了,然后用类似于滚动数组的东西做的。

#include<iostream>
#include<string.h>
#include<stdio.h>
using namespace std;
const int maxa = 9;
int dp[maxa][1<<maxa];
int dp1[maxa][1<<maxa];
char str[maxa][maxa];
int main(){
    int n ,m;
    while(scanf("%d%d", &n, &m)!=EOF){
        if(n==-1 && m== -1)
            return 0;
        memset(dp, 0, sizeof(dp));
        for(int i = 0; i < n; i++){
            scanf("%s", &str[i]);
        }
        memset(dp1, 0, sizeof(dp1));
        for(int i = 0;i < n; i++){
            for(int k = 0; k < n; k++){
                if(str[i][k] == '#'){
                    dp[1][1<<k] ++;
                    for(int j = m-1; j >=1; j--){
                        for(int l = 0; l < (1<<n); l++){
                            if((1<<k)&l){
                                dp[j+1][l] += dp1[j][l-(1<<k)];
                            }
                        }
                    }
                }
            }
            for(int j = 1; j <= m; j++){
                for(int k = 0; k < (1<<n); k++){
                    dp1[j][k] = dp[j][k];
                }
            }
        }
        int sum = 0;
        for(int i =0; i < (1<<n); i++){
            sum += dp[m][i];
        }
        printf("%d\n", sum);
    }
    return 0;
}
View Code

 

posted @ 2015-01-19 19:38  icodefive  阅读(66)  评论(0编辑  收藏  举报