您的位置:首页 > 其它

轮廓线DP POJ3254 && BZOJ 1087

2015-10-02 20:32 148 查看
补了一发轮廓线DP,发现完全没有必要从右往左设置状态,自然一点:

5 6 7 8 9

1 2 3 4

如此设置轮廓线标号,转移的时候直接把当前j位改成0或者1就行了。注意多记录些信息对简化代码是很有帮助的,尤其对于我这种代码经常错的一塌糊涂的人来说。。

呆马:

POJ 3254 Corn Fields

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
#define inf 1000000007
#define oo 100000000
#define maxn 11
#define maxm 1050

using namespace std;

int n,m,mb;
long long f[maxn][maxn][88][maxm];
int bit[maxm][maxn];

bool legal(int x, int y,int mask)
{
if (y==1)
{
if (bit[mask]
&bit[mask][n+1]) return 0;
if (bit[mask][n-1]&bit[mask][n+1]) return 0;
}
else
{
if (bit[mask][y-1]&bit[mask][n+1]) return 0;
if (bit[mask][y-2]&bit[mask][n+1]) return 0;
}
for (int i=1;i<n;i++) if (bit[mask][i]&bit[mask][i+1]) return 0;
return 1;
}

int main()
{
scanf("%d%d",&n,&m);
mb=(1<<(n+1))-1;
memset(bit,0,sizeof(bit));
for (int mask=0;mask<=mb;mask++)
{
int tmp=mask;
for (int i=1;i<=n+1;i++)
{
bit[mask][i]=tmp%2;
tmp/=2;
}
}
memset(f,0,sizeof(f));
f[0]
[0][0]=1;
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
for (int k=0;k<=m;k++)
for (int mask=0;mask<=mb;mask++)
if (legal(i,j,mask))
{
int tmp=1<<(j-1);
int ost=mask&(~tmp),nst=mask|tmp;
if (((mask>>(j-1))&1)!=((mask>>n)&1)) ost^=(1<<n),nst^=(1<<n);
if (j==1)
{
f[i][j][k][ost]+=f[i-1]
[k][mask];
if (k && !bit[mask][j] && !bit[mask][j+1] && !bit[mask][j-1])
f[i][j][k][nst]+=f[i-1]
[k-1][mask];
}
else
{
f[i][j][k][ost]+=f[i][j-1][k][mask];
if (k && !bit[mask][j] && !bit[mask][j+1] && !bit[mask][j-1] && !bit[mask][n+1])
f[i][j][k][nst]+=f[i][j-1][k-1][mask];
}
}
long long ans=0;
for (int mask=0;mask<=mb;mask++)
if (legal(n+1,1,mask))
{
ans+=f

[m][mask];
}
printf("%lld\n",ans);
return 0;
}


Kings
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: