poj3254(状态压缩dp)

来源:互联网 发布:淘宝上的内衣有图评论 编辑:程序博客网 时间:2024/04/30 19:01

链接:点击打开链接

题意:有一块N*M的空地,1表示可以播种,0表示不可以,现在要求播种并且播种区域不能相邻,输出所有可以播种情况的种数并对100,000,000区域

代码:

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <iostream>#include <algorithm>using namespace std;const long long mod=100000000;int n,m;int v[1<<15],d[15][15],dp[15][1<<15];           //dp[i][j]表示满足前i行的同时,第i行状态为j的情况数int judge(int x,int y){                         //判断当前状态是否满足当前行    int i;    for(i=0;i<m;i++)    if((y&(1<<i))&&!d[x][i])    return 0;    return 1;}int main(){    int i,j,k,u;    long long ans;    k=0;    for(i=0;i<(1<<12);i++){        if((i&(i<<1))==0)        v[k++]=i;    }                                           //预先处理横着没有相邻的状态    while(scanf("%d%d",&n,&m)!=EOF){        for(i=0;i<n;i++)        for(j=0;j<m;j++)        scanf("%d",&d[i][j]);        memset(dp,0,sizeof(dp));        for(i=0;i<n;i++){            for(j=0;v[j]<(1<<m);j++){           //当前状态满足当前行                if(judge(i,v[j])){                if(i==0)                dp[i][j]=1;                     //第一行每种情况都是1                else{                    for(u=0;v[u]<(1<<m);u++){   //v[u]为前一行的状态,看是否与当前行的状态v[j]矛盾                        if((v[j]&v[u])==0)                        dp[i][j]+=dp[i-1][u];                    }                }                }            }        }        ans=0;        for(i=0;v[i]<(1<<m);i++)                //最后一行所有的状态加和        ans=(ans+dp[n-1][i])%mod;        printf("%I64d\n",ans);    }    return 0;}


 

0 0
原创粉丝点击