JZOJ 3503. 粉刷(paint)

题目

Description

鸡腿想到了一个很高(sha)明(bi)的问题,墙可以看作一个N*M的矩阵,有一些格子是有污点的。现在鸡腿可以竖着刷一次,覆盖连续的最多C列,或者横着刷一次,覆盖连续的最多R行。现在鸡腿把墙上的情况告诉你,请你告诉鸡腿最少要刷多少次才能刷干净!
 

Input

第1行,输入俩正整数N,M。

第2到N+1行,每行一个长度为M的字符串,每个字符可能是’.’表示干净的,或者’X’表示这个格子有污点。

第N+2行,输入俩正整数表示R和C。

Output

输出一行一个整数,表示鸡腿最少要刷几次。
 

Sample Input

输入1:
1 9
XXXXXXXXX
2 3
输入2:

11 14
XXX..XXX..XXX.
.X..X....X...X
.X..X....X...X
.X..X....X...X
.X...XXX..XXX.
..............
...XX...XXX...
....X......X..
....X....XXX..
....X......X..
...XXX..XXX...
1 2

Sample Output

输出1:
1
输出2:
7
 

Data Constraint

对于50%的数据1≤N,M≤5;

对于100%的数据1≤N,M,R,C≤15。

 

分析

 

  • n=15
  • 那就枚举吧,枚举当前行刷不刷
  • 然后计算出列的答案加上取min

代码

 1 #include<iostream>
 2 #include<cstring>
 3 using namespace std;
 4 int b[20][20],a[20][20],ans=100000000;
 5 bool h[20],l[20],hh[20],ll[20];
 6 int n,m,r,c;
 7 int check()
 8 {
 9     int t=0;
10     memcpy(b,a,sizeof(b));
11     for (int i=1;i<=n;i++)
12       if (h[i]==1)
13         for (int j=1;j<=m;j++) 
14           b[i][j]=0;
15     for (int j=1;j<=m;j++)
16       for (int i=1;i<=n;i++)
17         if (b[i][j]==1) 
18         {
19             t++; 
20             j+=c-1;
21             break;
22         }
23     return t;
24 }
25 void dfs(int x,int sum)
26 {
27     if (x>n)
28     {
29         ans=min(ans,sum+check());
30         return;
31     }
32     for (int i=x;i<=min(x+r-1,n);i++)
33           h[i]=1;
34     dfs(min(x+r,n+1),sum+1);
35     for (int i=x;i<=min(x+r-1,n);i++)
36           h[i]=0;
37     dfs(x+1,sum);
38 }
39 int main ()
40 {
41     cin>>n>>m;
42     char num;
43     for (int i=1;i<=n;i++)
44         for (int j=1;j<=m;j++)
45         {
46             cin>>num; if (num=='X') a[i][j]=1;
47         }
48     cin>>r>>c;
49     dfs(1,0);
50     cout<<ans;
51 } 
原文地址:https://www.cnblogs.com/zjzjzj/p/11370579.html