最近做做搜索题吧。。。^_^

然后又被虐了。。。T T

这还是一道usaco题。。。我去。。。

 

为了方便叙述,FJ买的叫"木块",要被切掉的叫"木材"!!!(我也是醉了0.0)

根据贪心,我们肯定先搞到小的木块。。。于是先对要买的木块进行排序,然后二分答案

之后如何判断:

裸的dfs肯定过不掉T T,考虑优化

(1)如果两块木块长度相同,第一个已经被dfs过了且从第x块木材上被切下来,则第二个也至少要从第x块木材上切。(貌似是对称性原理的说。。。)

(2)某巨巨:"用waste表示每一个已经裁过的木材浪费的木材和,所谓浪费的木材就是最小的木块都比它大,那么他当前就已经裁不出任何木块了。就把这个木材加到waste去,如果waste>木材和-s[mid],说明这样裁木材是错误的,所以减枝。"

两个优化使得搜索速度快的飞起!!!

 

 1 /**************************************************************
 2     Problem: 1082
 3     User: rausen
 4     Language: C++
 5     Result: Accepted
 6     Time:4 ms
 7     Memory:820 kb
 8 ****************************************************************/
 9  
10 #include <cstdio>
11 #include <cstring>
12 #include <algorithm>
13  
14 using namespace std;
15 const int N = 1005;
16 int n, m, waste, l, r, mid;
17 int a[N], b[N], c[N], s[N], T;
18  
19 inline int read(){
20     int x = 0;
21     char ch = getchar();
22     while (ch < '0' || ch > '9')
23         ch = getchar();
24  
25     while (ch >= '0' && ch <= '9'){
26         x = x * 10 + ch - '0';
27         ch = getchar();
28     }
29     return x;
30 }
31  
32 bool dfs(int x, int pos){
33     if (!x) return 1;
34     if (s[mid] + waste > T) return 0;
35     for (int i = pos; i <= m; ++i)
36         if (c[i] >= b[x]){
37             c[i] -= b[x];
38             if (c[i] < b[1])
39                 waste += c[i];
40             if (b[x] == b[x - 1]){
41                 if (dfs(x - 1, i))
42                     return 1;
43             }
44             else if (dfs(x - 1, 1)) return 1;
45             if (c[i] < b[1]) waste -= c[i];
46             c[i] += b[x];
47         }
48     return 0;
49 }
50  
51 int main(){
52     m = read();
53     for (int i = 1; i <= m; ++i)
54         a[i] = read(), T += a[i];
55     n = read();
56     for (int i = 1; i <= n; ++i)
57         b[i] = read();
58     sort(a + 1, a + m + 1);
59     sort(b + 1, b + n + 1);
60     for (int i = 1; i <= n; ++i)
61         s[i] = s[i - 1] + b[i];
62     while (s[n] > T) --n;
63     l = 0, r = n + 1;
64     while (l + 1 < r){
65         waste = 0;
66         memcpy(c, a, sizeof(a));
67         mid = l + r >> 1;
68         if (dfs(mid, 1)) l = mid;
69         else r = mid;
70     }
71     printf("%d\n", l);
72     return 0;
73 }
View Code

 

posted on 2014-10-28 20:43  Xs酱~  阅读(456)  评论(0编辑  收藏  举报