poj1321 棋盘问题,状态压缩dp

好久不做题了。

虽然是水题,还是写个解题报告吧。

普通的暴搜要8^8的复杂度,还是有点危险的。
随便想一下可以发现这题存在最优子结构等动态规划的要素,所以可以用状态压缩DP解决。
状态就是每层,当前已有哪几个列已被占。二维。
转移就是两种:
1.当前行不加棋子,就是f[i][j]+=f[i-1][j];
2.当前行加一个棋子,就是f[i][newst]+=f[i-1][j],而且加棋子的位置不能是空白的。
最后将最后一行棋子数等于k的状态的方案数求和即可。
复杂度O(2^8*8*8),比搜索好了许多。Poj的水数据0ms。


#include
#include
#include
using namespace std;
#define NN 300

int num[NN],f[12][NN];//f[i][j]表示在做到第i行,满足行状态为j时的可行方案总数
int n;
char g[12][12];



void cal(int now){ //计算某个状态有几个位置被占,也就是已放有几个棋子,存在num[]中
    int i,j,tmp,cnt;
    tmp=1;
    cnt=0;
    for(i=1;i<=n;++i){
        if (now&tmp) cnt+=1;
        tmp=tmp<<1;
    }
    num[now]=cnt;
}


int main(){
    int i,j,l,k,status,newst,ans;
    while(1){
        scanf("%d%d",&n,&k);
        if (n==-1&&k==-1) break;
        for(i=1;i<=n;++i){
            scanf("%s",g[i]+1);
        }
        status=1<





你可能感兴趣的:(dp,POJ)