BZOJ_2621
由于物品不多,可以直接搜过去。对于当前一个物品,无非有两种决策,要么放到前面的某些背包里,要么新开辟一个背包,另外再判断一下当前的背包数是不是已经超过了或者等于最优解来剪一下枝。
#include<stdio.h> #include<string.h> #include<algorithm> #include<queue> #define INF 0x3f3f3f3f int N, W, a[20], ANS, r[20]; void dfs(int dep, int n) { if(n >= ANS) return; if(dep == N) { ANS = std::min(ANS, n); return ; } for(int i = 0; i < n; i ++) if(r[i] >= a[dep]) { r[i] -= a[dep]; dfs(dep + 1, n); r[i] += a[dep]; } r[n] -= a[dep]; dfs(dep + 1, n + 1); r[n] += a[dep]; } void solve() { ANS = N; for(int i = 0; i < N; i ++) r[i] = W; dfs(0, 0); printf("%d\n", ANS); } int main() { while(scanf("%d%d", &N, &W) == 2) { for(int i = 0; i < N; i ++) scanf("%d", &a[i]); solve(); } return 0; }