码迷,mamicode.com
首页 > 其他好文 > 详细

轮廓线DP POJ3254

时间:2015-10-02 21:10:53      阅读:181      评论:0      收藏:0      [点我收藏+]

标签:

补了一发轮廓线DP,发现完全没有必要从右往左设置状态,自然一点:

           5 6 7 8 9

1 2 3 4

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

呆马:

技术分享
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
#define inf 1000000007
#define oo 100000000
#define maxn 15
#define maxm 5200

using namespace std;

int n,m,mb;
int a[maxn][maxn];
int f[maxn][maxn][5000];
int bit[5000][maxn];

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

int main()
{
    scanf("%d%d",&n,&m);
    memset(a,0,sizeof(a));
    for (int i=1;i<=n;i++)
        for (int j=1;j<=m;j++)
            scanf("%d",&a[i][j]);
    mb=(1<<m)-1;
    for (int mask=0;mask<=mb;mask++)
    {
        int tmp=mask;
        for (int i=1;i<=m;i++)
        {
            bit[mask][i]=tmp%2;
            tmp/=2;
        }
    }
    memset(f,0,sizeof(f));
    f[0][m][0]=1;
    for (int i=1;i<=n;i++)
        for (int j=1;j<=m;j++)
            for (int mask=0;mask<=mb;mask++)
                if (legal(i,j,mask))
                {
                    int tmp=1<<(j-1);
                    if (j==1)
                    {
                        f[i][j][mask&(~tmp)]+=f[i-1][m][mask];
                        f[i][j][mask&(~tmp)]%=oo;
                        if (!bit[mask][j] && a[i][j])
                        {
                            f[i][j][mask|tmp]+=f[i-1][m][mask];
                            f[i][j][mask|tmp]%=oo;
                        }
                    }
                    else
                    {
                        f[i][j][mask&(~tmp)]+=f[i][j-1][mask];
                        f[i][j][mask&(~tmp)]%=oo;
                        if (!bit[mask][j] && a[i][j])
                        {
                            f[i][j][mask|tmp]+=f[i][j-1][mask];
                            f[i][j][mask|tmp]%=oo;
                        }
                    }
                }
    int ans=0;
    for (int mask=0;mask<=mb;mask++)
        if (legal(n+1,1,mask))
        {
            ans+=f[n][m][mask];
            ans%=oo;
        }
    printf("%d\n",ans);
    return 0;
}
Corn Fields

 

轮廓线DP POJ3254

标签:

原文地址:http://www.cnblogs.com/zig-zag/p/4852676.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!