Scales POJ - 3172

原题链接

考察:dfs+剪枝

思路:

        很像小猫爬山的分组问题,但这里只考虑一组.涉及剪枝:

  1. 排除冗余:组合型枚举
  2. 最优剪枝: 如果前面所有物品和+当前w都<ans return
  3. 搜索顺序剪枝:很明显从大到小搜索.

注意这道题最优性剪枝不能是当前w<ans return. 因为可能n个小的拼凑出更大的.

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 #include <algorithm>
 5 using namespace std;
 6 typedef long long LL;
 7 const int N = 1010;
 8 int n,a[N],C;
 9 LL ans,sum[N];
10 void dfs(int st,LL w)
11 {
12     if(ans==C||w+sum[st]<=ans) return;
13     if(w>ans) ans = w;
14     if(w+sum[st]<=C&&w+sum[st]>ans)
15     {
16         ans = w+sum[st];
17         return;
18     }
19      for(int i=st;i>=1;i--)
20     {
21         if(w+a[i]<=C)
22          dfs(i-1,w+a[i]);
23     }
24 }
25 int main()
26 {
27     scanf("%d%d",&n,&C);
28     for(int i=1;i<=n;i++) scanf("%d",&a[i]),sum[i]=sum[i-1]+a[i];
29     if(C<a[1]) ans = 0;
30     else dfs(n,0);
31     printf("%lld\n",ans);
32     return 0;
33 } 

 

思考:

        最优性剪枝是要当前状况的答案与ans比较,而不是只考虑部分答案.

posted @ 2021-03-10 01:20  acmloser  阅读(24)  评论(0编辑  收藏  举报