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 */