1、芯片(chip.pas/cpp)

【问题描述】
企鹅集成电路公司生产了一种大小为 2×3的芯片。每块芯片是从一块大小为N×M的硅
片上切下来的,但由于原材料纯度问题,因而有若干的单位正方形并不能作为芯片的一部分。
企鹅集成电路公司想要知道,给定一块 N×M大小的硅片和坏掉的单位正方形的位置,最
多能使用这块硅片生产多少芯片?

【输入格式】
输入的第一行由一个正整数 D 构成,表示硅片的个数。
随后跟着 D 个数据,每个数据第一行包含三个整数 N,M,K,分别表示硅片的长和宽,
以及硅片坏掉的单位正方形个数。
接下 K 行,每行两个整数 X , Y ,表示单位正方形的坐标。
注:左上角的单位正方形用 (1,1) 表示,右下角的单位正方形用 (N,M) 表示。

【输出格式】
共 D 行,每行一个整数,即最多能切出多少个芯片。

【输入样例】

1
6 6 5
1 4
4 6
2 2
3 6
6 4

【输出样例】
3

【数据范围】
对于 10% 的数据,K=0;
对于另 外10%的数据,1≤M≤5,K≤1;
对于40%的数据,1≤M≤8;
最后一个测试点,空间限制8MB,其余限制64MB。
对于所有数据,1≤D≤5,1≤N≤150,1≤M≤10,0≤K≤M。

好。看一看就发现是状压DP,不会写,写了个搜索拿40分,稳的很。

  1 #include <cstdio>
  2 #include <cstring>
  3 
  4 const int N = 160;
  5 
  6 bool vis[N][12];
  7 int ans, n, m;
  8 
  9 inline void read(int &x) {
 10     x = 0;
 11     char c = getchar();
 12     while(c > '9' || c < '0') {
 13         c = getchar();
 14     }
 15     while(c >= '0' && c <= '9') {
 16         x = (x << 3) + (x << 1) + c - 48;
 17         c = getchar();
 18     }
 19     return;
 20 }
 21 
 22 inline int getmax(int x, int y) {
 23     int tp = 0;
 24     for(int i = x; i <= n; i++) {
 25         for(int j = (i == x) ? y : 1; j <= m; j++) {
 26             if(!vis[i][j]) {
 27                 tp++;
 28             }
 29         }
 30     }
 31     return tp / 6;
 32 }
 33 
 34 inline bool valid1(int x, int y) {
 35     if(x + 2 > n || y + 1 > m) {
 36         return 0;
 37     }
 38     for(int i = x; i <= x + 2; i++) {
 39         for(int j = y; j <= y + 1; j++) {
 40             if(vis[i][j]) {
 41                 return 0;
 42             }
 43         }
 44     }
 45     return 1;
 46 }
 47 
 48 inline bool valid2(int x, int y) {
 49     if(x + 1 > n || y + 2 > m) {
 50         return 0;
 51     }
 52     for(int i = x; i <= x + 1; i++) {
 53         for(int j = y; j <= y + 2; j++) {
 54             if(vis[i][j]) {
 55                 return 0;
 56             }
 57         }
 58     }
 59     return 1;
 60 }
 61 
 62 void DFS(int k, int x, int y) {
 63     if(k > ans) {
 64         ans = k;
 65     }
 66     if(y > m) {
 67         y = 1;
 68         x++;
 69     }
 70     if(x > n) {
 71         return;
 72     }
 73     int t = getmax(x, y);
 74     if(k + t <= ans) {
 75         return;
 76     }
 77     for(int i = x; i <= n; i++) {
 78         for(int j = (i == x) ? y : 1; j <= m; j++) {
 79             if(valid1(i, j)) {
 80                 for(int a = i; a <= i + 2; a++) {
 81                     vis[a][j] = 1;
 82                     vis[a][j + 1] = 1;
 83                 }
 84                 DFS(k + 1, i, j + 1);
 85                 for(int a = i; a <= i + 2; a++) {
 86                     vis[a][j] = 0;
 87                     vis[a][j + 1] = 0;
 88                 }
 89             }
 90             if(valid2(i, j)) {
 91                 for(int b = j; b <= j + 2; b++) {
 92                     vis[i][b] = 1;
 93                     vis[i + 1][b] = 1;
 94                 }
 95                 DFS(k + 1, i, j + 1);
 96                 for(int b = j; b <= j + 2; b++) {
 97                     vis[i][b] = 0;
 98                     vis[i + 1][b] = 0;
 99                 }
100             }
101         }
102     }
103     return;
104 }
105 
106 int main() {
107     freopen("chip.in", "r", stdin);
108     freopen("chip_bf.out", "w", stdout);
109     int T;
110     read(T);
111     while(T--) {
112         int k;
113         ans = 0;
114         memset(vis, 0, sizeof(vis));
115         read(n); read(m); read(k);
116         for(int i = 1, x, y; i <= k; i++) {
117             read(x); read(y);
118             vis[x][y] = 1;
119         }
120 
121         DFS(0, 1, 1);
122 
123         printf("%d\n", ans);
124     }
125 
126     return 0;
127 }
40分搜索

相关文章:

  • 2021-06-02
  • 2021-12-24
  • 2021-05-19
  • 2022-12-23
  • 2021-08-12
  • 2021-12-23
  • 2021-07-17
  • 2021-04-01
猜你喜欢
  • 2021-11-28
  • 2021-06-01
  • 2021-12-09
  • 2021-07-06
  • 2021-08-19
  • 2022-12-23
  • 2022-01-01
相关资源
相似解决方案