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 }
View Code

 

posted @ 2015-08-31 20:08  一麻袋码的玛侬  阅读(243)  评论(0编辑  收藏  举报