#include <cstdio> #include <algorithm> #include <vector> #include <set> using namespace std; bool pack(const vector<int>&, vector<int>&); bool pack2(const vector<int> &items, vector<int> &packs, long long cap) { int n = items.size(); long long tmp = 0; vector<int> p1,p2; for (int x: packs) { tmp += x; if (2*tmp <= cap || p1.empty()) p1.push_back(x); else p2.push_back(x); } for (int i=1; i<(1<<n)-1; i++) { vector<int> i1,i2; for (int j=0; j<n; j++) if ((i&(1<<j)) == 0) i1.push_back(items[j]); else i2.push_back(items[j]); if (pack(i1,p1) && pack(i2,p2)) return true; } return false; } set < pair < vector<int>, vector<int> > > used[30][30]; const int OPS = 1e8; int Count; inline bool pack(const vector<int> &items, vector<int> &packs) { Count++; if (items.back() > packs.back()) return false; long long sum = 0; for (int x: items) sum += x; long long cap = 0; for (int x: packs) cap += x; if (cap < sum) return false; if (packs.size() == 1) return cap >= sum; if (used[items.size()][packs.size()].count(make_pair(items,packs))) return false; int n = items.size(); int s = packs.back(); if (Count > OPS && s > 11) return pack2(items, packs, cap); int m = (1<<n)-1; for (int i=1; i<m; i++) { if (Count > OPS && s > 11) return false; vector<int> v; long long tmp = 0; for (int j=0; j<n; j++) if ((i&(1<<j)) == 0) v.push_back(items[j]); else tmp += items[j]; long long r = 0; for (int x: packs) r += min((long long)x,tmp); if (tmp > s || tmp + v[0] <= s || r < sum || v[0] > packs[0]) continue; packs.pop_back(); if (pack(v, packs)) return true; packs.push_back(s); } used[items.size()][packs.size()].insert(make_pair(items,packs)); return false; } int main() { int n,m,a; vector<int> items, packs; scanf("%d%d", &n,&m); for (int i=0; i<n; i++) { scanf("%d", &a); items.push_back(a); } for (int i=0; i<m; i++) { scanf("%d", &a); packs.push_back(a); } sort(items.begin(), items.end()); sort(packs.begin(), packs.end()); reverse(packs.begin(), packs.end()); while (m > n) packs.pop_back(), m--; vector<int> used_packs; used_packs.push_back(packs[0]); int res = 1; while (res <= m && !pack(items,used_packs)) { used_packs.insert(used_packs.begin(), packs[res++]); } if (res <= m) printf("%d\n", res); else printf("NIE\n"); 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 | #include <cstdio> #include <algorithm> #include <vector> #include <set> using namespace std; bool pack(const vector<int>&, vector<int>&); bool pack2(const vector<int> &items, vector<int> &packs, long long cap) { int n = items.size(); long long tmp = 0; vector<int> p1,p2; for (int x: packs) { tmp += x; if (2*tmp <= cap || p1.empty()) p1.push_back(x); else p2.push_back(x); } for (int i=1; i<(1<<n)-1; i++) { vector<int> i1,i2; for (int j=0; j<n; j++) if ((i&(1<<j)) == 0) i1.push_back(items[j]); else i2.push_back(items[j]); if (pack(i1,p1) && pack(i2,p2)) return true; } return false; } set < pair < vector<int>, vector<int> > > used[30][30]; const int OPS = 1e8; int Count; inline bool pack(const vector<int> &items, vector<int> &packs) { Count++; if (items.back() > packs.back()) return false; long long sum = 0; for (int x: items) sum += x; long long cap = 0; for (int x: packs) cap += x; if (cap < sum) return false; if (packs.size() == 1) return cap >= sum; if (used[items.size()][packs.size()].count(make_pair(items,packs))) return false; int n = items.size(); int s = packs.back(); if (Count > OPS && s > 11) return pack2(items, packs, cap); int m = (1<<n)-1; for (int i=1; i<m; i++) { if (Count > OPS && s > 11) return false; vector<int> v; long long tmp = 0; for (int j=0; j<n; j++) if ((i&(1<<j)) == 0) v.push_back(items[j]); else tmp += items[j]; long long r = 0; for (int x: packs) r += min((long long)x,tmp); if (tmp > s || tmp + v[0] <= s || r < sum || v[0] > packs[0]) continue; packs.pop_back(); if (pack(v, packs)) return true; packs.push_back(s); } used[items.size()][packs.size()].insert(make_pair(items,packs)); return false; } int main() { int n,m,a; vector<int> items, packs; scanf("%d%d", &n,&m); for (int i=0; i<n; i++) { scanf("%d", &a); items.push_back(a); } for (int i=0; i<m; i++) { scanf("%d", &a); packs.push_back(a); } sort(items.begin(), items.end()); sort(packs.begin(), packs.end()); reverse(packs.begin(), packs.end()); while (m > n) packs.pop_back(), m--; vector<int> used_packs; used_packs.push_back(packs[0]); int res = 1; while (res <= m && !pack(items,used_packs)) { used_packs.insert(used_packs.begin(), packs[res++]); } if (res <= m) printf("%d\n", res); else printf("NIE\n"); return 0; } |