poj1321
这题深搜不会啊,就会状压dp,好久没敲代码了,有些要注意的地方都忘了,dp要注意不要出现多余情况,恩。。。就是。。。就像背包一样某些物品智能装一个,就要从后向前一面装多了,我这题就碰到这种问题了,然后用类似于滚动数组的东西做的。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#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; }