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 }

时间: 2024-10-12 08:18:42

HDU 5113 dfs剪枝的相关文章

hdu 4109 dfs+剪枝优化

求最久时间即在无环有向图里求最远路径 dfs+剪枝优化 从0节点(自己增加的)出发,0到1~n个节点之间的距离为1,mt[i]表示从0点到第i个节点目前所得的最长路径 #include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> #include<vector> using namespace std; const

hdu 1584 dfs+剪枝

蜘蛛牌 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3730    Accepted Submission(s): 1591 Problem Description 蜘蛛牌是windows xp操作系统自带的一款纸牌游戏,游戏规则是这样的:只能将牌拖到比她大一的牌上面(A最小,K最大),如果拖动的牌上有按顺序排好的牌时,那么这些牌也

hdu 1728 DFS+剪枝 逃离迷宫

1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 5 typedef struct Node 6 { 7 int x, y; 8 }Node; 9 10 const int MAX = 10000; 11 const int N = 110; 12 const int dir[4][2] = { {-1,0}, {0,1}, {1,0}, {0,-1} };//移动方向 13 bool

hdu 1010 dfs+剪枝

Tempter of the Bone Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 119601 Accepted Submission(s): 32313 Problem Description The doggie found a bone in an ancient maze, which fascinated him a lot.

hdu 1445 dfs剪枝

题意比较简单:重点在剪枝上. #include<stdio.h> #include<string.h> #include<algorithm> #include<iostream> using namespace std; int n,num[70],mark[70],k,flash; int dfs(int s,int ii,int t,int c) { if(t==c) { flash=1; return 1; } if(flash) return 0;

hdu 5305 dfs+剪枝

思路:对每一条边涂上颜色1或-1,颜色值加到关联的两个点上,则一种成功的方案必须满足最后每个点的值为0. 剪枝:统计出和某个点i相关联的边的个数,如果枚举到某一条边的时候发现:abs(sum[i]) > degree[i],则剪去,其中sun[i]表示i点的值,degree[i]表示剩下的还没有枚举的和i关联的边的个数. 1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 using n

hdu 1518 dfs+剪枝

题目大意:几根棒子能否组成一个正方形 Sample Input3           //测试组数4 1 1 1 1   //棒子数目以及每根棒子的长度5 10 20 30 40 508 1 7 2 6 4 4 3 5 Sample Output yesnoyes 虽然不用pos直接从0开始枚举也可以有答案,但会超时,加个pos,以前dfs过的情况就不会再出现了,想起以前bc的一道题也是这样 1 #include<cstdio> 2 #include<iostream> 3 #in

HDU 1010 Tempter of the Bone dfs+剪枝

给你一个迷宫一个起点和一个终点,问你能否走T步刚好到达终点,不能重复走,并且只有4个方向 显然这是一个dfs,虽然N最大只有7,但是裸的dfs复杂度还是太高了,因此要进行一些剪枝 1.如果T比图上所有的可走点还要大,肯定是不可行的.这个可以避免dfs整张图. 2.奇偶剪枝,有性质当前点(x,y)到目标点(tx,ty)的所有路径的长度的奇偶性一定和|x-tx|+|y-ty|一样. #include <cstdio> #include <iostream> #include <c

hdu 1010 Tempter of the Bone (DFS+剪枝)

Tempter of the Bone Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 68206    Accepted Submission(s): 18719 Problem Description The doggie found a bone in an ancient maze, which fascinated him a