#include <cstdio> #include <vector> #include <algorithm> using namespace std; typedef long long LL; int n, m; int *arr; int size; int best = 999; int minimum = -1; LL sumItems = 0; int items[32]; int knapsacks[105]; int bitMasks[32], negMasks[32]; void solve(int num, int mask, LL sum, int bit, int lastNotTaken){ if(mask == 0){ if(num < best) best = num; return; } if(best <= minimum || arr[mask] <= num) return; while(bit < n && (mask & bitMasks[bit]) == 0) ++bit; if(bit < n){ if(sum + items[bit] <= knapsacks[num]) solve(num, mask & negMasks[bit], sum + items[bit], bit + 1, lastNotTaken); solve(num, mask, sum, bit + 1, items[bit]); }else{ int num1 = num + 1; if(arr[mask] > num1) if(num1 < best && num1 < m && num1 < n) if(lastNotTaken == 0 || sum + lastNotTaken > knapsacks[num]){ solve(num1, mask, 0, 0, 0); arr[mask] = num1; } } } int main(){ int a, c; LL sumKnapsacks = 0; scanf("%d%d", &n, &m); for(int i=0; i<n; i++){ scanf("%d", &a); items[i] = a; sumItems += a; } for(int i=0; i<m; i++){ scanf("%d", &c); sumKnapsacks += c; knapsacks[i] = c; } size = 1 << n; arr = new int[size]; for(int i=0; i<size; i++) arr[i] = 999; sort(items, items + n); sort(knapsacks, knapsacks + m); reverse(items, items + n); reverse(knapsacks, knapsacks + m); sumKnapsacks = 0; for(int i=0; i<n; i++){ sumKnapsacks += knapsacks[i]; if(sumKnapsacks >= sumItems){ minimum = i; break; } } for(int i=0; i<n; i++){ bitMasks[i] = (1 << i); negMasks[i] = ~(1 << i); } if(minimum >= 0) solve(0, size - 1, 0, 0, 0); if(best > 200) printf("NIE\n"); else printf("%d\n", best + 1); delete [] arr; return 0; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | #include <cstdio> #include <vector> #include <algorithm> using namespace std; typedef long long LL; int n, m; int *arr; int size; int best = 999; int minimum = -1; LL sumItems = 0; int items[32]; int knapsacks[105]; int bitMasks[32], negMasks[32]; void solve(int num, int mask, LL sum, int bit, int lastNotTaken){ if(mask == 0){ if(num < best) best = num; return; } if(best <= minimum || arr[mask] <= num) return; while(bit < n && (mask & bitMasks[bit]) == 0) ++bit; if(bit < n){ if(sum + items[bit] <= knapsacks[num]) solve(num, mask & negMasks[bit], sum + items[bit], bit + 1, lastNotTaken); solve(num, mask, sum, bit + 1, items[bit]); }else{ int num1 = num + 1; if(arr[mask] > num1) if(num1 < best && num1 < m && num1 < n) if(lastNotTaken == 0 || sum + lastNotTaken > knapsacks[num]){ solve(num1, mask, 0, 0, 0); arr[mask] = num1; } } } int main(){ int a, c; LL sumKnapsacks = 0; scanf("%d%d", &n, &m); for(int i=0; i<n; i++){ scanf("%d", &a); items[i] = a; sumItems += a; } for(int i=0; i<m; i++){ scanf("%d", &c); sumKnapsacks += c; knapsacks[i] = c; } size = 1 << n; arr = new int[size]; for(int i=0; i<size; i++) arr[i] = 999; sort(items, items + n); sort(knapsacks, knapsacks + m); reverse(items, items + n); reverse(knapsacks, knapsacks + m); sumKnapsacks = 0; for(int i=0; i<n; i++){ sumKnapsacks += knapsacks[i]; if(sumKnapsacks >= sumItems){ minimum = i; break; } } for(int i=0; i<n; i++){ bitMasks[i] = (1 << i); negMasks[i] = ~(1 << i); } if(minimum >= 0) solve(0, size - 1, 0, 0, 0); if(best > 200) printf("NIE\n"); else printf("%d\n", best + 1); delete [] arr; return 0; } |