思维的可扩展性&poj1185

  突然想到这么一个词语,觉得很重要。

  最近在看状态压缩dp,因为不会状压,所以还找了那个ppt去看,外面又百度看了几篇博客,感受一下那个写法。我自己第一道状态压缩dp,之前自己写的深搜是这种的:

void dfs(int cur,int st,int count)
{
    if(cur==m)
    {
        state[tot]=st;
        stanum[tot++]=count;
        return;
    }
    flg[cur+1]=0;
    dfs(cur+1,st<<1,count);
    if(flg[cur-1]+flg[cur]==0)
    {
         flg[cur+1]=1;
         dfs(cur+1,st<<1|1,count+1);
    }
}
View Code

  后来又改了一下,我自己觉得没什么问题,因为的确有对拍过,可是不知道就是哪里不对。。

void dfs(int cur,int st,int count)
{
    if(cur==m)
    {
        state[tot]=st;
        stanum[tot++]=count;
        return;
    }
    flg[cur+1]=0;
    dfs(cur+1,st<<1,count);
    if(cur<1)
    {
        flg[cur+1]=1;
        dfs(cur+1,st<<1|1,count+1);
    }
    else
    {
        if(flg[cur-1]+flg[cur]==0)
        {
            flg[cur+1]=1;
            dfs(cur+1,st<<1|1,count+1);
        }
    }
}
View Code

  完整代码:

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <queue>

using namespace std;

const int maxn=100+5;
const int maxm=10+5;

int n,m,tot;
int state[65],stanum[65];
int in[maxn];
bool flg[maxm];
//char s[maxn][maxm];

void dfs(int cur,int st,int count)
{
    if(cur==m)
    {
        state[tot]=st;
        stanum[tot++]=count;
        return;
    }
    flg[cur+1]=0;
    dfs(cur+1,st<<1,count);
    if(cur<1)
    {
        flg[cur+1]=1;
        dfs(cur+1,st<<1|1,count+1);
    }
    else
    {
        if(flg[cur-1]+flg[cur]==0)
        {
            flg[cur+1]=1;
            dfs(cur+1,st<<1|1,count+1);
        }
    }
}

void init()
{
    tot=0;
    dfs(0,0,0);
}

void data_in()
{
    char tmp;
    for(int i=1;i<=n;i++)
    {
        in[i]=0;
        getchar();
        for(int j=1;j<=m;j++)
        {
            scanf("%c",&tmp);
//            s[i][j]=tmp;
            in[i]=in[i]*2+(tmp=='H'?1:0);
        }
    }
}

int dp[2][65][65];
void DP()
{
    memset(dp,-1,sizeof(dp));
    for(int i=0;i<tot;i++)
    {
        if(in[1]&state[i]) continue;
        dp[1][i][0]=stanum[i];
    }
    int now=1;
    for(int i=2;i<=n;i++)
    {
        now^=1;
        for(int j=0;j<tot;j++)
        {
            if(in[i]&state[j]) continue;
            else for(int k=0;k<tot;k++)
            {
                if(state[j]&state[k]) continue;
                else for(int l=0;l<tot;l++)
                {
                    if(state[j]&state[l]) continue;
                    else if(dp[now^1][k][l]==-1) continue;
                    else dp[now][j][k]=max(dp[now][j][k],dp[now^1][k][l]+stanum[j]);
                }
            }
        }
    }
    int ans=0;
    for(int i=0;i<tot;i++)
    {
        for(int j=0;j<tot;j++)
            ans=max(ans,dp[now][i][j]);
    }
    printf("%d\n",ans);
}

int main()
{
    while(~scanf("%d %d",&n,&m))
    {
        init();
        data_in();
        DP();
    }
    return 0;
}
View Code
勸君惜取少年時&莫待無花空折枝
原文地址:https://www.cnblogs.com/RainingDays/p/3083872.html