Scales POJ - 3172
考察:dfs+剪枝
思路:
很像小猫爬山的分组问题,但这里只考虑一组.涉及剪枝:
- 排除冗余:组合型枚举
- 最优剪枝: 如果前面所有物品和+当前w都<ans return
- 搜索顺序剪枝:很明显从大到小搜索.
注意这道题最优性剪枝不能是当前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比较,而不是只考虑部分答案.