poj 3254 상태 압축 DP

7801 단어 poj
사고방식: 각 줄의 수를 하나의 2진법으로 간주하고 0은 변하지 않고 1은 변하지 않는다. 모든 합법적인 2진법 형식이 표시하는 정수, 즉 서로 인접한 것이 1이다. 그러면 i-1줄과 i줄의 상태 이동 방정식은 dp[i][j]+=dp[i-1][k]이다.
이 방정식의 전제 조건은num[i][j]&num[i-1][k]==0이다. 즉, 그들이 표시한 2진법 형식이 0이면 인접이 1인 상황이 존재하지 않는다.
#include<iostream>

#include<cstdio>

#include<cstring>

#include<algorithm>

#define Maxn 13

#define inf 0x7fffffff

using namespace std;

__int64 dp[Maxn][1<<Maxn];

int num[13][1<<Maxn],cnt1,cnt2,graphic[Maxn][Maxn],co,n,m;

void dfs(int u,int j)

{

    int i;

    if(j==m)

    {

        int sum=0;

        for(i=m;i>=1;i--)

            sum+=graphic[u][i]*(1<<(m-i));

        if(graphic[u][j]==1)

        {

            if(graphic[u][j-1]==0)

            {



                num[u][++cnt2]=sum;

                num[u][++cnt2]=sum-1;

            }

            else

            {

                num[u][++cnt2]=sum-1;

            }

        }

        else

            num[u][++cnt2]=sum;

        return ;

    }

    if(graphic[u][j]==1)

    {

        if(graphic[u][j-1]==0)

        {

            dfs(u,j+1);

            graphic[u][j]=0;

            dfs(u,j+1);

            graphic[u][j]=1;

        }

        else

        {

            graphic[u][j]=0;

            dfs(u,j+1);

            graphic[u][j]=1;

        }

    }

    else

        dfs(u,j+1);

}

int main()

{

    int i,j,k;

    while(scanf("%d%d",&n,&m)!=EOF)

    {

        memset(dp,0,sizeof(dp));

        for(i=1;i<=n;i++)

            for(j=1;j<=m;j++)

            scanf("%d",&graphic[i][j]);

        for(i=1;i<=n;i++)

            graphic[i][0]=0;

        cnt2=0;

        dfs(1,1);

        for(i=1;i<=cnt2;i++)

            dp[1][i]=1;

        for(i=2;i<=n;i++)

        {

            cnt1=cnt2;cnt2=0;

            dfs(i,1);

            for(j=1;j<=cnt2;j++)

            {

                for(k=1;k<=cnt1;k++)

                {

                    if(!(num[i-1][k]&num[i][j]))

                    dp[i][j]+=dp[i-1][k],dp[i][j]%=100000000;

                }

            }

        }

        __int64 ans=0;

        for(i=1;i<=cnt2;i++)

        ans+=dp[n][i];

        printf("%I64d
",ans%100000000); } return 0; }

좋은 웹페이지 즐겨찾기