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 }