Bugs公司(bugs  1S  256M 

问题描述

生记茶餐厅由于受杀人事件的影响,生意日渐冷清,不得不暂时歇业。四喜赋闲在家,整天抱着零食看电视,在大家的提醒下才开始注意自己日益发福的形象,下定决心减肥,萌发了去工作压力大的电脑公司打工的念头。于是,她应聘到了Bugs公司,这是一家专门生产硬件的企业。初来乍到,四喜被分配到车间进行产品组装,工作就是把公司生产的一种2*3单位尺寸的芯片嵌入N*M单位尺寸的模板内。模板接受过严格检查,损坏的单位小方格已被标上黑色记号,如下图所示。

嵌入芯片的要求是,放置芯片的区域内不能有黑色记号,同时芯片与芯片之间不能重叠。公司为了追求利益,希望将尽量多的芯片嵌入模板,这可难坏了那批工人。四喜向你求助,希望你能帮她计算出可能嵌入的最大芯片数量。

 

输入文件:(input.txt)

首行包含三个整数N、M、K,分别表示模板的规模及损坏的单位方格的数目(0≤K≤NM),接下来K行描述各损坏方格,每行包括2个数X、Y(1≤X≤N,1≤Y≤M)(左上角坐标为(1,1),右下角坐标为(N,M)。

数据范围:1≤N≤150,1≤M≤10。

输出文件(output.txt):

包含一个整数,即可能嵌入的最大芯片数。

输入样例

6 6 5        

1 4

4 6

2 2

3 6

6 4

输出样例

3

分析

 初看此题毫无疑问状态压缩,但是为什么n这么小呢,(考后才知道不可能用矩阵加速)

 我一下就想到了普通的状态压缩 但是这题不可能用2进制得出(除非两层状态枚举。。 2 ^20,70分)

 好吧,3进制!

0 表示 00

1 表示 01

2 表示 11(1表示此格被占,0则反之)

再加上原本就不能占用的格子,蛋疼dfs转移。。。。

1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<string.h>
4 int f[160][59049] = {0},n,m,k;
5 int map[160][100]={0},tk = 1;
6 int g[59049][100],v[59049][100],d[59049] = {0},a[12],b[12];
7 int hash[59049] = {0},ans = 0,mx = 0;
8 // 0 00
9 // 1 10
10 // 2 11
11 void init()
12 {
13 int x,y;
14 scanf("%d %d %d",&n,&m,&k);
15 for(int i = 1;i <= m;i++) tk = tk * 3;
16 tk--;
17 for(int i = 1;i <= k;i++)
18 {
19 scanf("%d %d",&x,&y);
20 map[x][y] = 1;
21 }
22 memset(f,-1,sizeof(f));
23 for(int i = 1;i <= m;i++) map[0][i] = 1;
24 f[0][tk] = 0;
25 }
26 int max(int x,int y) {if (x > y) return x; return y;}
27 void dfs(int C,int h,int x,int w)
28 {
29 if (x == 0)
30 {
31 int now = 0;
32 for(int i = 1;i <= m;i++) now = now * 3 + b[i];
33 // for(int i = 1;i <= m;i++) printf("%d",b[i]);
34 f[h + 1][now] = max(f[h + 1][now],f[h][C] + w);
35 // printf(" :%d %d\n",w,f[h + 1][now]);
36 ans = max(ans,f[h + 1][now]);
37 return;
38 }
39 int ta[20],tb[20];
40 if (x >= 3 && a[x] < 2 && a[x - 1] < 2 && a[x - 2] < 2 && map[h + 1][x] == 0 && map[h + 1][x - 1] == 0 && map[h + 1][x - 2] == 0){
41 ta[x] = a[x]; ta[x - 1] = a[x - 1]; ta[x - 2] = a[x - 2];
42 tb[x] = b[x]; tb[x - 1] = b[x - 1]; tb[x - 2] = b[x - 2];
43 b[x] = b[x - 1] = b[x - 2] = 2;
44 dfs(C,h,x - 3,w + 1);
45 a[x] = ta[x]; a[x - 1] = ta[x - 1]; a[x - 2] = ta[x - 2];
46 }
47 if (x >= 2 && a[x] == 0 && a[x - 1] == 0 && map[h + 1][x] == 0 && map[h + 1][x - 1] == 0){
48 ta[x] = a[x]; ta[x - 1] = a[x - 1];
49 tb[x] = b[x]; tb[x - 1] = b[x - 1];
50 b[x] = b[x - 1] = 2;
51 dfs(C,h,x - 2,w + 1);
52 a[x] = ta[x]; a[x - 1] = ta[x - 1];
53 }
54 if (map[h + 1][x] == 1) b[x] = 2;
55 else if (a[x] == 2) b[x] = 1;
56 else b[x] = 0;
57 dfs(C,h,x - 1,w);
58 }
59 void work()
60 {
61 for(int i = 0;i <= n - 1;i++)
62 {
63 // printf("------------------------\n");
64 // printf("step %d ::\n",i);
65 for(int j = 0;j <= tk;j++)
66 {
67 if (f[i][j] == -1) continue;
68 int x = j,flag = 1;
69 for(int k = m;k >= 1;k--) {
70 a[k] = x % 3;
71 x /= 3;
72 }
73 // for(int k = 1;k <= m;k++)
74 // printf("%d",a[k]);
75 // printf(" :::::::::::\n");
76 dfs(j,i,m,0); // j 状态 第i行 第m列,可以放w个
77 }
78 // system("pause");
79
80 }
81 }
82 int main()
83 {
84 freopen("input.txt","r",stdin);
85 freopen("output.txt","w",stdout);
86 init();
87 work();
88 printf("%d\n",ans);
89 // system("pause");
90 return 0;
91 }