原创、转载请注明出处
每个物品放或不放,想象一个长度为n的数组,每个位置是0或者是1(放或不放),暴力枚举的话,复杂度是2n,题目给的时间是1秒,一般n(物品的数量)的规模可达到26,题目给的n的最大值是20,暴力枚举应该能过,用递归枚举加剪枝肯定能过。
01串可用二进制枚举,也可用向量枚举,我用的是递归枚举,方便剪枝(解答树的枝)。
代码如下:
#include<iostream> using namespace std; const int maxn = 20; int A[maxn], n, c, bn, ans; void f(int cur, int put, int packNum, int packMass, int itemNum) { if(packNum > bn) { ans = max(ans, itemNum - 1); return; } if(cur == n || ((put == 1) && (A[cur] > c))) { ans = max(ans, itemNum); return; } if(!put) { f(cur + 1, 0, packNum, packMass, itemNum); f(cur + 1, 1, packNum, packMass, itemNum); } else { if(A[cur] + packMass > c) { f(cur + 1, 0, packNum + 1, A[cur], itemNum + 1); f(cur + 1, 1, packNum + 1, A[cur], itemNum + 1); } else { f(cur + 1, 0, packNum, packMass + A[cur], itemNum + 1); f(cur + 1, 1, packNum, packMass + A[cur], itemNum + 1); } } } int main() { int t; cin >> t; while(t --) { cin >> n >> c >> bn; for(int i = 0 ;i < n ; i++) { cin >> A[i]; } ans = 0; f(0, 0, 1, 0, 0); f(0, 1, 1, 0, 0); cout << ans << endl; } }
牛客的判错明显不对,容量11的背包,比11小的物品有6个,不可能输出13.
以下是我的输出案例: