2013 Asia Nanjing Regional Contest C
Campus Design
Time Limit: 15000/8000 MS (Java/Others)
Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 184 Accepted Submission(s): 92
(1)可以放1*2的块、1*1的块,分别根据其特点转移即可
(2)1*1的块有个数要求;增加一维表示用的1* 1块个数即可
(3)有些格子不能放,有些格子能放;分两种情况进行转移即可
dp[i][s][k]表示:i阶段s状态使用有k个1*1块时的覆盖方案总数(共n*m各阶段,每个阶段(1 <<m)- 1个状态)
注意转移情况及转移时的条件
Problem Description
Nanjing University of Science and Technology is celebrating its 60th anniversary. In order to make room for student activities, to make the university a more pleasant place for learning, and to beautify the campus, the college administrator decided to start construction on an open space. The designers measured the open space and come to a conclusion that the open space is a rectangle with a length of n meters and a width of m meters. Then they split the open space into n x m squares. To make it more beautiful, the designer decides to cover the open space with 1 x 1 bricks and 1 x 2 bricks, according to the following rules:
1. All the bricks can be placed horizontally or vertically 2. The vertexes of the bricks should be placed on integer lattice points 3. The number of 1 x 1 bricks shouldn’t be less than C or more than D. The number of 1 x 2 bricks is unlimited. 4. Some squares have a flowerbed on it, so it should not be covered by any brick. (We use 0 to represent a square with flowerbet and 1 to represent other squares)
Now the designers want to know how many ways are there to cover the open space, meeting the above requirements.
1. All the bricks can be placed horizontally or vertically 2. The vertexes of the bricks should be placed on integer lattice points 3. The number of 1 x 1 bricks shouldn’t be less than C or more than D. The number of 1 x 2 bricks is unlimited. 4. Some squares have a flowerbed on it, so it should not be covered by any brick. (We use 0 to represent a square with flowerbet and 1 to represent other squares)
Now the designers want to know how many ways are there to cover the open space, meeting the above requirements.
Input
There are several test cases, please process till EOF. Each test case starts with a line containing four integers N(1 <= N <= 100), M(1 <= M <= 10), C, D(1 <= C <= D <= 20). Then following N lines, each being a string with the length of M. The string consists of ‘0’ and ‘1’ only, where ‘0’ means the square should not be covered by any brick, and ‘1’ otherwise.
Output
Please print one line per test case. Each line should contain an integers representing the answer to the problem (mod 109 + 7).
Sample Input
1 1 0 0
1
1 1 1 2
0
1 1 1 2
1
1 2 1 2
11
1 2 0 2
01
1 2 0 2
11
2 2 0 0
10
10
2 2 0 0
01
10
2 2 0 0
11
11
4 5 3 5
11111
11011
10101
11111
Sample Output
0
0
1
1
1
2
1
0
2
954
Source
Recommend
1 #pragma comment(linker,"/STACK:102400000,102400000") 2 #include <cstdio> 3 #include <vector> 4 #include <cmath> 5 #include <queue> 6 #include <cstring> 7 #include <iostream> 8 #include <algorithm> 9 using namespace std; 10 #define INF 0x7fffffff 11 #define mod 1000000007 12 #define ll long long 13 #define maxn 1025 14 #define pi acos(-1.0) 15 int n, m, x, y, a, b ,now, all, v; 16 char s[maxn][maxn]; 17 int dp[2][maxn][22]; 18 void update(int vs,int s,int vk,int k){ 19 if (vs&(1 << m))dp [v][vs^(1<<m)][vk] = (dp [v][vs^(1<<m)][vk] + dp [now][s][k]) % mod; 20 } 21 int main(){ 22 while (~scanf("%d%d%d%d",&n,&m,&a,&b)){ 23 for (int i = 0; i < n; i++)scanf("%s", s[i]); 24 memset(dp, 0, sizeof dp); 25 now = 0; 26 all = (1 << m) - 1; 27 dp[0][all][0] = 1; 28 for (int i = 0; i < n; i++) 29 for (int j = 0; j < m; j++){ 30 v = now ^ 1; 31 if (s[i][j] == '0'){ 32 for (int k = 0; k <= b;k++) 33 for (int cur = 0; cur <= all; cur++) 34 if(dp[now][cur][k])update((cur<<1)^1,cur,k,k); 35 } 36 else{ 37 for (int k = 0; k <= b; k++) 38 for(int cur =0;cur <= all; cur++) 39 if(dp[now][cur][k]){ 40 update(cur<<1,cur,k,k); 41 update((cur<<1)^1,cur,k+1,k); 42 if (j&&!(cur&1))update((cur<<1)^3,cur,k,k); 43 if (i&&!(cur&(1<<(m-1))))update((cur<<1)^(1<<m)^1,cur,k,k); 44 } 45 } 46 memset(dp[now], 0, sizeof dp[now]); 47 now ^= 1; 48 } 49 int ans = 0; 50 for (int i = a; i <= b; i++)ans = (ans + dp[now][all][i]) % mod; 51 printf("%d\n", ans); 52 } 53 return 0; 54 }
浙公网安备 33010602011771号