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 }

 

你可能感兴趣的:(Rails)