POJ 1038 Bugs Integrated, Inc.3进制压缩

题意:在n*m的棋盘中,求2*3木块的最大覆盖数(不允许木块重叠,且有些无法覆盖的点)。

做法:3进制压缩状态,此时的状态会用数组记录,而且为了方便,数组从 0开始,表示每一行的状态,而行数是从1开始记录的,所以在记录无法覆盖的点的时候要注意这个改变,否则。。。,写挫了,人品好才没超时1800MS,伤不起。。。

#include<stdio.h>
#include<string.h>
bool blo[150][12];
short dp[155][60000];
int state1[12],state2[12];
int pow[12];
int n,m;
//行列已经翻转。
inline short max(short a,short b)
{
    return a>b?a:b;
}
void work(void)
{
    pow[0]=1;
    for(int i=1;i<=10;i++)
    pow[i]=3*pow[i-1];
}
int ctod(int *state)
{
    int i,s=0;
    for(i=0;i<m;i++)
    s+=state[i]*pow[i];
    return s;
}
void dtoc(int s,int *state)
{
    for(int i=0;i<m;i++,s/=3)
      state[i]=s%3;
}
void init()
{
    int i;
    memset(state2,0,sizeof(state2));
    for(i=0;i<m;i++)
    state1[i]=1;
    dp[0][ctod(state1)]=0;
}
void dfs(int i,int lie,int get)
{
    if(lie>=m)
    {
        int x=ctod(state1);
        dp[i][x]=max(dp[i][x],get);
        return ;
    }
    dfs(i,lie+1,get);
    if(lie+2<m&&blo[i][lie]==0&&blo[i][lie+1]==0&&blo[i][lie+2]==0
       &&blo[i+1][lie]==0&&blo[i+1][lie+1]==0&&blo[i+1][lie+2]==0
       &&state1[lie]==0&&state1[lie+1]==0&&state1[lie+2]==0)
    {
        state1[lie]=state1[lie+1]=state1[lie+2]=2;
        dfs(i,lie+3,get+1);
        state1[lie]=state1[lie+1]=state1[lie+2]=0;
    }
    if(lie+1<m&&state2[lie]==0&&state2[lie+1]==0&&state1[lie]==0&&state1[lie+1]==0
       &&blo[i][lie]==0&&blo[i][lie+1]==0&&blo[i-1][lie]==0&&blo[i-1][lie+1]==0
       &&blo[i+1][lie]==0&&blo[i+1][lie+1]==0)
    {
        state1[lie]=state1[lie+1]=2;
        dfs(i,lie+2,get+1);
        state1[lie]=state1[lie+1]=0;
    }
}
int main()
{
    int i,D,k,j;
    short ans;
    work();
    scanf("%d",&D);
    while(D--)
    {
        scanf("%d%d%d",&n,&m,&k);
        memset(dp,-1,sizeof(dp));
        memset(blo,0,sizeof(blo));
        while(k--)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            y--;//就是这里了,要注意。。。。
            blo[x][y]=1;
        }
        init();
        for(i=1;i<n;i++)
          for(j=0;j<pow[m];j++)
          if(dp[i-1][j]!=-1)
          {
              dtoc(j,state2);
              for(int t=0;t<m;t++)
                 state1[t]=(state2[t]-1>0);
              dfs(i,0,dp[i-1][j]);
          }
          ans=0;
          for(j=0;j<pow[m];j++)
          ans=max(ans,dp[n-1][j]);
          printf("%d\n",ans);
    }
    return 0;
}


你可能感兴趣的:(POJ 1038 Bugs Integrated, Inc.3进制压缩)