#include <cstdio> #include <vector> #include <map> #include <algorithm> #include <set> #include <deque> #define REP(i, n) for (int i = 0; i < (n); ++i) #define FOR(i, a, b) for (int i = (a); i < (b); ++i) using namespace std; const int MAX_N = 24; const int MAX_M = 110; int n, m; int d[MAX_N]; int p[MAX_M]; const int MAX_W = (1<<24) + 5; int sum[MAX_W]; vector<int> moves; char w[MAX_W]; // FIXME: pamiec? int sum_one(int mask, int limit) { int res = 0; REP(i, n) { if (mask & (1<<i)) { res += d[i]; if (res > limit) break; } } return res; } void licz_sum() { FOR(i, 1, (1<<n)) { sum[i] = sum_one(i, p[0]); } } void licz_inne_moves(int bin) { moves.clear(); FOR(i, 1, (1<<n)) { if (sum[i] <= p[bin]) { int first = n-1; while (i & (1<<first)) first--; if (sum[i] + d[first] <= p[bin]) continue; moves.push_back(i); } } } bool dajesz(int bin) { licz_inne_moves(bin); for (int pos = (1<<n)-1; pos >= 0; pos--) { if (w[pos] != bin+1) continue; REP(i, moves.size()) { int x = moves[i]; if (!w[pos|x]) { w[pos | x] = bin+2; } } if ((pos & (pos+1)) == 0) break; } return w[(1<<n)-1]; } int main() { scanf("%d %d", &n, &m); REP(i, n) scanf("%d", &d[i]); REP(i, m) scanf("%d", &p[i]); sort(d, d+n, greater<int>()); sort(p, p+m, greater<int>()); m = min(m, n); long long total = 0; REP(i, n) total += d[i]; if (total <= (long long)(p[0])) { printf("1\n"); return 0; } licz_sum(); REP(i, MAX_W) w[i] = 0; w[0] = 1; REP(i, m) { // printf("bin = %d\n", i); if (dajesz(i)) { printf("%d\n", i+1); return 0; } } 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 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | #include <cstdio> #include <vector> #include <map> #include <algorithm> #include <set> #include <deque> #define REP(i, n) for (int i = 0; i < (n); ++i) #define FOR(i, a, b) for (int i = (a); i < (b); ++i) using namespace std; const int MAX_N = 24; const int MAX_M = 110; int n, m; int d[MAX_N]; int p[MAX_M]; const int MAX_W = (1<<24) + 5; int sum[MAX_W]; vector<int> moves; char w[MAX_W]; // FIXME: pamiec? int sum_one(int mask, int limit) { int res = 0; REP(i, n) { if (mask & (1<<i)) { res += d[i]; if (res > limit) break; } } return res; } void licz_sum() { FOR(i, 1, (1<<n)) { sum[i] = sum_one(i, p[0]); } } void licz_inne_moves(int bin) { moves.clear(); FOR(i, 1, (1<<n)) { if (sum[i] <= p[bin]) { int first = n-1; while (i & (1<<first)) first--; if (sum[i] + d[first] <= p[bin]) continue; moves.push_back(i); } } } bool dajesz(int bin) { licz_inne_moves(bin); for (int pos = (1<<n)-1; pos >= 0; pos--) { if (w[pos] != bin+1) continue; REP(i, moves.size()) { int x = moves[i]; if (!w[pos|x]) { w[pos | x] = bin+2; } } if ((pos & (pos+1)) == 0) break; } return w[(1<<n)-1]; } int main() { scanf("%d %d", &n, &m); REP(i, n) scanf("%d", &d[i]); REP(i, m) scanf("%d", &p[i]); sort(d, d+n, greater<int>()); sort(p, p+m, greater<int>()); m = min(m, n); long long total = 0; REP(i, n) total += d[i]; if (total <= (long long)(p[0])) { printf("1\n"); return 0; } licz_sum(); REP(i, MAX_W) w[i] = 0; w[0] = 1; REP(i, m) { // printf("bin = %d\n", i); if (dajesz(i)) { printf("%d\n", i+1); return 0; } } printf("NIE\n"); return 0; } |