HDOJ 2442 -bricks 状态压缩DP 一直TLE.打表过的..

    有5个砖块..加上一个空着不放..那么有6种状态..所以很明显的可以用6进制的状态DP...

    不过这么做..我觉得我已经能优化的都优化了...还是超时..一看数据范围是100*6..打表先AC了..

    看有大神用3进制状态DP水过..Orz...看了好久没看懂...觉得自己状态DP还是很表面~~


Program:

 

#include<iostream>

#include<stdio.h>

#include<string.h>

#include<set>

#include<algorithm>

#include<cmath>

#define oo 1000000007

#define ll long long

#define pi acos(-1.0)

#define MAXN 505

using namespace std;

int sharp[6][6][2]={{{0,0},{0,0},{0,0},{0,0},{0,0}},

                    {{0,0},{1,0},{1,1},{2,0},{-1,-1}},

                    {{0,1},{1,0},{1,1},{1,2},{2,1}},

                    {{0,0},{0,1},{0,2},{1,1},{-1,-1}},

                    {{0,0},{0,1},{0,2},{1,0},{-1,-1}},

                    {{0,0},{0,1},{1,0},{2,0},{-1,-1}}

                   };

int n,m,canuse[132],w[132],tall[132],dp[101][132][132],num,step[6]={0,4,5,4,4,4};

bool f[132][132][2];

bool legal(int x)  // 判断这一行这么安排是否合法

{ 

      int i,j,t=x,a[10][10]; 

      memset(a,0,sizeof(a));

      w[num+1]=0;  

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

      {

            if (i+1>m && (x%6==1 || x%6==5)) return false;

            if (i+2>m && (x%6==2 || x%6==3 || x%6==4)) return false;

            for (j=0;j<step[x%6];j++)

               a[sharp[x%6][j][0]][i+sharp[x%6][j][1]-1]++;

            w[num+1]+=step[x%6];

            x/=6;

      }

      for (i=0;i<10;i++)

         for (j=0;j<10;j++)

           if (a[i][j]>1) return false;

      tall[num+1]=0;   

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

      {  

            if (t%6==1 || t%6==2 || t%6==5)

               tall[num+1]=2;

            else

               if (t%6!=0 && tall[num+1]<1) 

              tall[num+1]=1;

            t/=6;

      }

      return true;

} 

bool ok(int a,int b,int tp) //判断是否冲突

{

      int i,j,h[10][10];

      a=canuse[a],b=canuse[b]; 

      memset(h,0,sizeof(h));

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

      {

             for (j=0;j<step[a%6];j++) 

                h[sharp[a%6][j][0]][i+sharp[a%6][j][1]-1]++;

             a/=6;

      }

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

      {

             for (j=0;j<step[b%6];j++) 

                h[sharp[b%6][j][0]-tp][i+sharp[b%6][j][1]-1]++;

             b/=6;          

      }

      for (i=0;i<10;i++)

         for (j=0;j<10;j++)

           if (h[i][j]>1) return false;

      return true;

}

int main()

{

      freopen("input.txt","r",stdin); freopen("output.txt","w",stdout);

      int r,i,j,x,ans,totol;

      while (~scanf("%d%d",&n,&m))

      {

           totol=1;

           for (i=1;i<=m;i++) totol*=6;

           num=0;

           for (i=0;i<totol;i++)

              if (legal(i)) canuse[++num]=i; 

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

           memset(f,true,sizeof(f));

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

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

               for (x=1;x<=2;x++)

                 f[i][j][x]=ok(i,j,x);

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

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

                if (tall[i]+r<=n) 

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

                    if (f[i][j][1])

                       for (x=1;x<=num;x++)

                         if (f[i][x][2]) 

                           dp[r][j][i]=max(dp[r][j][i],dp[r-1][x][j]+w[i]);

 

           ans=0;

           for (i=1;i<=num;i++) ans=max(ans,dp[n][i][1]);

           printf("%d,",ans);

      } 

      return 0;

}


 

 

你可能感兴趣的:(压缩)