HDU 5113 dfs剪枝
题意:告诉格子规格,颜色个数,以及每个颜色能涂得格子数目,问是否能够实现相邻两个格子的颜色数目不相同。
分析:因为数据很小,格子最多是5 * 5大小的,因此可以dfs。TLE了一次之后开始剪枝,31ms过。剪枝看代码。
1 #include <cstdio>
2 #include <iostream>
3 #include <sstream>
4 #include <cmath>
5 #include <cstring>
6 #include <cstdlib>
7 #include <string>
8 #include <vector>
9 #include <map>
10 #include <set>
11 #include <queue>
12 #include <stack>
13 #include <algorithm>
14 using namespace std;
15 #define ll long long
16 #define _cle(m, a) memset(m, a, sizeof(m))
17 #define repu(i, a, b) for(int i = a; i < b; i++)
18 #define repd(i, a, b) for(int i = b; i >= a; i--)
19 #define sfi(n) scanf("%d", &n)
20 #define pfi(n) printf("%d\n", n)
21 #define MAXN 26
22 int n, m, k, tot;
23 int c[MAXN];
24 int mpp[5][5], re[5][5];
25 int tcc[MAXN];
26 void put(int mp[][5])
27 {
28 repu(i, 0, n)
29 {
30 repu(j, 0, m)
31 if(j == 0)
32 printf("%d", mp[i][j]);
33 else printf(" %d", mp[i][j]);
34 puts("");
35 }
36 }
37 bool Judge(int tc[], int cur)///剪枝,剩下没染的颜色中的数目如果超过一半就break
38 {
39 repu(i, 0, k) if(c[i] - tc[i] > (tot - cur + 1) / 2) return true;
40 return false;
41 }
42 int debug(int cur,int mp[][5])
43 {
44 cout<<cur<<endl;
45 put(mp);
46 }
47 bool dfs(int cur, int tc[], int mp[][5])
48 {
49 ///当前已经染得格子数目,当前染得每个颜色剩下的数目,当前的已经订好的方案
50 ///debug(cur,mp);
51 if(cur >= n * m) return true;
52 int x = cur / m;
53 int y = cur - x * m;
54 if(Judge(tc, cur)) return false;
55 repu(i, 0, k)
56 {
57 if(tc[i] < c[i])
58 {
59 if(x - 1 >= 0 && mp[x - 1][y] == i + 1)
60 continue;
61 if(y - 1 >= 0 && mp[x][y - 1] == i + 1)
62 continue;
63 tc[i]++;
64 mp[x][y] = i + 1;
65 if(dfs(cur + 1, tc, mp))
66 return true;
67 tc[i]--;
68 }
69 }
70 return false;
71 }
72 int main()
73 {
74 int T;
75 sfi(T);
76 repu(kase, 1, T + 1)
77 {
78 sfi(n), sfi(m), sfi(k);
79 tot = n * m;
80 repu(i, 0, k) sfi(c[i]);
81 _cle(tcc, 0);
82 _cle(mpp, 0);
83 printf("Case #%d:\n", kase);
84 if(dfs(0, tcc, mpp))
85 {
86 printf("YES\n");
87 put(mpp);
88 }
89 else
90 printf("NO\n");
91 }
92 return 0;
93 }
人生就像心电图,想要一帆风顺,除非game-over