HDU 4804 Campus Design

这个题目还是蛮简单的; 状态压缩的经典题吗  只是增加了一维变量;多开一维搞定

#include<iostream>
#include<stdio.h>
#include<cstring>
#include<algorithm>
#include<cmath>
#define mod  1000000007
using namespace std;

int N,M,C,D;
__int64 dp[4][3000][22];
char map[105][22];

void dfs( int sta,int lev,int stu,int n,int k,__int64 num )
{
    if( sta >= M || k > D)return;
	dfs( sta+1,lev,stu,n,k,num );
	if( map[lev][sta] == '1' && (stu&(1<<sta)) == 0 )
	{
		int t = stu+(1<<sta);
		dp[n][t][k+1]+=num; dp[n][t][k+1] %= mod;
		dfs(sta+1,lev,t,n,k+1,num);
	}
	if( sta + 1 < M && map[lev][sta] == '1' && map[lev][sta+1] == '1' )
	if( (stu&(1<<sta)) == 0 && (stu&(1<<(sta+1))) == 0  )
	{
		int t = stu+(1<<sta); t = t+(1<<(sta+1));
		dp[n][t][k]+=num; dp[n][t][k] %= mod;
		dfs(sta+2,lev,t,n,k,num);
	}
}
void work( )
{
	int i,j,k,s,t=1,num = (1<<M); memset( dp,0,sizeof(dp) ); dp[t][num-1][0] = 1;
	for( i = 1; i <= N; i++ )
	{
        s = t^1;
        for( j = 0; j < num; j++ )
        for( k = 0; k <= D;  k++ )
        {
          if( dp[t][j][k] == 0 )continue; __int64 stu = 0; bool fell = false;
          for( int x = 0; x < M; x++ )
            if( map[i-1][x] != '0' && (j&(1<<x)) == 0 )
            {
				  if( map[i][x] == '0' ) fell = true;
			      else stu += (1<<x);
            }
            if( fell )continue;
			dp[s][stu][k] = dp[t][j][k];
			dfs( 0,i,stu,s,k,dp[t][j][k] );
        }
        for( j = 0; j < num; j++ )
        for( k = 0; k <= D;  k++ )
        dp[t][j][k] = 0;
        t = s;
    }
	__int64 res = 0; int now = 0;
	for( j = 0; j < M; j++ )if( map[N][j] != '0' ) now +=(1<<j);
	for( j = C; j <= D;  j++ ) res += dp[t][now][j],res %= mod;
	printf("%I64d\n",res);
}
int main( )
{
      while( scanf("%d%d%d%d",&N,&M,&C,&D) != EOF ){
		  memset(map,'0',sizeof(map));
          for( int i = 1; i <= N; i++ )
			scanf("%s",map[i]);
		  work( );
	  }
	  return 0;
}
/*
2 3  1 2
111
101
*/

  

你可能感兴趣的:(HDU 4804 Campus Design)