您的位置:首页 > 其它

POJ --3254--Corn Fields--状态DP

2013-04-27 17:23 246 查看
状态DP上手~

和炮兵阵地很相似的道理,会了炮兵阵地就会这个了。

同样的思路,当前行的状态由上一行的可行状态整合而来,具体思路见代码

#include<iostream>
#include<cstring>
#include<cstdio>
#define maxn 20
#define dbug1
#define M 100000000
using namespace std;
const int maxStatu=1<<13;
int bmp[maxn][maxn];
int sp[maxn];
int n,m;
int sc,st[maxStatu];
int dp[maxn][maxStatu];
void init()
{
memset(dp,0,sizeof(sp));
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
scanf("%d",&bmp[i][j]);
sp[i]|=bmp[i][j]*(1<<(m-j));
}
}
sc=0;
int nms=1<<m;
#ifdef dbug
printf("this is status:\n");
#endif
for(int i=0;i<nms;i++)
{
if(i&(i<<1))continue;
st[sc++]=i;
#ifdef dbug
printf("%d ",i);
#endif
}
#ifdef dbug
printf("\n");
#endif
}
void solve()
{
memset(dp,0,sizeof(dp));
for(int i=0;i<sc;i++)
{
if((sp[1]&st[i])!=st[i])continue;
dp[1][st[i]]=1;
}
for(int i=2;i<=n;i++)
{
for(int j=0;j<sc;j++)  //枚举第 i 行状态
{
if((st[j]&sp[i])!=st[j])continue;	//判断第  i 能否放置状态 st[j]

for(int k=0;k<sc;k++)  //枚举第 i-1 行状态
{
if(st[k]&st[j])continue;
#ifdef dbug
printf("st1---%d st2--%d\n",st[j],st[k]);
#endif
dp[i][st[j]]+=dp[i-1][st[k]];
dp[i][st[j]]%=M;
}
}
}
int ans=0;
for(int i=0;i<sc;i++)
{
ans+=dp
[st[i]];
ans%=M;
}
printf("%d\n",ans);
}

int main()
{
init();
solve();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: