USACO 4.1 Fence rails(迭代加深DFS+二分)

没思路,实在是没想出如何爆搜。

查看题解,认真研究了nocow上的7个提示,然后发现我还是不会写,无奈之下,看别人代码,看了很多份,终于过了。。。

用到了迭代搜索(dfsid),就是说确定搜索的层数,将问题转化为n个木头能否切成k块木板,因为贪心策略,k块木板肯定是最小的k块,这样的搜索以前好像没这样写过,二分再加上两个优化就可以过了。加的是 浪费量和标记搜索木头,详细请看nocow上题解把。。。这份代码wood和board都是从小到大排的,把board从大到小排,同样也可以过,而且更快一点,但是wood必须从小到大。。。第二个优化必须根据wood从小到大。

 1 /*
 2        ID: cuizhe
 3        LANG: C++
 4        TASK: fence8
 5 */
 6 #include <iostream>
 7 #include <cstdio>
 8 #include <cstring>
 9 #include <cmath>
10 #include <algorithm>
11 #include <map>
12 #include <string>
13 #include <vector>
14 using namespace std;
15 int board[55];
16 int wood[1024],temp[1024];
17 int wsum[1024];
18 int n,r,z;
19 int maxz;
20 void dfs(int mid,int start)
21 {
22     int i,waste = 0,num = 1;
23     if(z) return ;
24     if(mid == 0)
25     {
26        z = 1;
27        return ;
28     }
29     for(i = 1;i <= n;i ++)
30     {
31         if(temp[i] < wood[1])
32         waste += temp[i];
33     }
34     if(waste > maxz) return ;
35     for(i = start;i <= n;i ++)
36     {
37         if(temp[i] >= wood[mid])
38         {
39             if(mid-1 >= 1&&wood[mid] == wood[mid-1])
40             num = i;
41             else
42             num = 1;
43             temp[i] -= wood[mid];
44             dfs(mid-1,num);
45             temp[i] += wood[mid];
46         }
47     }
48     return ;
49 }
50 int main()
51 {
52     int i,str,end,mid,sum = 0;
53     freopen("fence8.in","r",stdin);
54     freopen("fence8.out","w",stdout);
55     scanf("%d",&n);
56     for(i = 1; i <= n; i ++)
57     {
58         scanf("%d",&board[i]);
59         sum += board[i];
60     }
61     sort(board+1,board+n+1);
62     for(i = 1;i <= n;i ++)
63     {
64         temp[i] = board[i];
65     }
66     scanf("%d",&r);
67     for(i = 1; i <= r; i ++)
68         scanf("%d",&wood[i]);
69     sort(wood+1,wood+r+1);
70     for(i = 1; i <= r; i ++)
71     {
72         wsum[i] = wsum[i-1] + wood[i];
73     }
74     str = 0;
75     end = r;
76     while(str < end)
77     {
78         mid = (str + end + 1)/2;
79         maxz = sum - wsum[mid];
80         z = 0;
81         dfs(mid,1);
82         if(!z)
83         {
84             end = mid - 1;
85         }
86         else
87         {
88             str = mid;
89         }
90     }
91     printf("%d\n",str);
92     return 0;
93 }

 

posted @ 2013-02-19 19:19  Naix_x  阅读(298)  评论(0编辑  收藏  举报