#include <stdlib.h> #include <string.h> //---===--- #include <stdio.h> #include <unistd.h> typedef unsigned int uint; char buf_in[4096000]; int buf_in_head = 0; int buf_in_tail = 0; static int getChar(void) { while (buf_in_head == buf_in_tail) { int rv = read(0, buf_in, sizeof(buf_in)); if (rv > 0) { buf_in_head = 0; buf_in_tail = rv; break; }; if (rv == 0) return EOF; } return buf_in[buf_in_head++]; } // only 1 call is safe, and only if previously getChar() had been called. static void ungetChar(void) { --buf_in_head; } static uint getUInt() { uint v; int c; for (;;) { c = getChar(); if (c < '0') continue; if (c > '9') continue; v = c - '0'; break; }; for (;;) { c = getChar(); if (c < '0') break; if (c > '9') break; v *= 10; v += c - '0'; }; ungetChar(); return v; } //---===--- #define C24 24 uint a[C24]; // przedmioty uint c[100]; // plecaki uint T[1 << C24]; // 64MB, dynamika tu sie dzieje int cmp(const uint * x, const uint * y) { if (*x < *y) return -1; if (*x > *y) return +1; return 0; } int void_incr_cmp(const void * x, const void * y) { return cmp((const uint*)x, (const uint*)y); } int void_decr_cmp(const void * x, const void * y) { return -cmp((const uint*)x, (const uint*)y); } int main (void) { int n, m, tsize; int i, j, k, p; // przedmioty: 1 <= n <= 24 n = getUInt(); // paczki: 1 <= m <= 100 m = getUInt(); tsize = 1 << n; for (i = 0; i < n; ++i) a[i] = getUInt(); // 1 <= a[i] <= 100,000,000 for (i = 0; i < m; ++i) c[i] = getUInt(); // 1 <= c[i] <= 100,000,000 qsort(a, n, sizeof(a[0]), void_incr_cmp); // przedmioty rosnaca qsort(c, m, sizeof(c[0]), void_decr_cmp); // paczki malejaco // zatrzymujemy n najwiekszych paczek if (m > n) m = n; // 1 <= {paczki} m <= {przedmioty} n <= 24 //for (i = 0; i < n; ++i) printf("%d ", a[i]); putchar('\n'); // low to high //for (i = 0; i < m; ++i) printf("%d ", c[i]); putchar('\n'); // high to low // must: INF > c[p] >= c[0] >= 10**8 // 0x06060606 == 101058054 // #define INF (100000000 + 1) memset(T, 0xFF, sizeof(T[0]) * tsize); // INF T[0] = 0; // for all p for (p = 0; p < m; ++p) { uint limit = c[p]; for (i = 0; i < tsize; ++i) { uint v = T[i]; if (v > limit) continue; T[i] = 0; for (j = 0, k = 1; j < n; ++j, k <<= 1) { if (i & k) continue; uint w = v + a[j]; if (w > limit) break; if (w < T[i + k]) T[i + k] = w; }; }; if (T[tsize - 1] > limit) continue; printf("%d\n", p + 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 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 | #include <stdlib.h> #include <string.h> //---===--- #include <stdio.h> #include <unistd.h> typedef unsigned int uint; char buf_in[4096000]; int buf_in_head = 0; int buf_in_tail = 0; static int getChar(void) { while (buf_in_head == buf_in_tail) { int rv = read(0, buf_in, sizeof(buf_in)); if (rv > 0) { buf_in_head = 0; buf_in_tail = rv; break; }; if (rv == 0) return EOF; } return buf_in[buf_in_head++]; } // only 1 call is safe, and only if previously getChar() had been called. static void ungetChar(void) { --buf_in_head; } static uint getUInt() { uint v; int c; for (;;) { c = getChar(); if (c < '0') continue; if (c > '9') continue; v = c - '0'; break; }; for (;;) { c = getChar(); if (c < '0') break; if (c > '9') break; v *= 10; v += c - '0'; }; ungetChar(); return v; } //---===--- #define C24 24 uint a[C24]; // przedmioty uint c[100]; // plecaki uint T[1 << C24]; // 64MB, dynamika tu sie dzieje int cmp(const uint * x, const uint * y) { if (*x < *y) return -1; if (*x > *y) return +1; return 0; } int void_incr_cmp(const void * x, const void * y) { return cmp((const uint*)x, (const uint*)y); } int void_decr_cmp(const void * x, const void * y) { return -cmp((const uint*)x, (const uint*)y); } int main (void) { int n, m, tsize; int i, j, k, p; // przedmioty: 1 <= n <= 24 n = getUInt(); // paczki: 1 <= m <= 100 m = getUInt(); tsize = 1 << n; for (i = 0; i < n; ++i) a[i] = getUInt(); // 1 <= a[i] <= 100,000,000 for (i = 0; i < m; ++i) c[i] = getUInt(); // 1 <= c[i] <= 100,000,000 qsort(a, n, sizeof(a[0]), void_incr_cmp); // przedmioty rosnaca qsort(c, m, sizeof(c[0]), void_decr_cmp); // paczki malejaco // zatrzymujemy n najwiekszych paczek if (m > n) m = n; // 1 <= {paczki} m <= {przedmioty} n <= 24 //for (i = 0; i < n; ++i) printf("%d ", a[i]); putchar('\n'); // low to high //for (i = 0; i < m; ++i) printf("%d ", c[i]); putchar('\n'); // high to low // must: INF > c[p] >= c[0] >= 10**8 // 0x06060606 == 101058054 // #define INF (100000000 + 1) memset(T, 0xFF, sizeof(T[0]) * tsize); // INF T[0] = 0; // for all p for (p = 0; p < m; ++p) { uint limit = c[p]; for (i = 0; i < tsize; ++i) { uint v = T[i]; if (v > limit) continue; T[i] = 0; for (j = 0, k = 1; j < n; ++j, k <<= 1) { if (i & k) continue; uint w = v + a[j]; if (w > limit) break; if (w < T[i + k]) T[i + k] = w; }; }; if (T[tsize - 1] > limit) continue; printf("%d\n", p + 1); return 0; }; printf("NIE\n"); return 0; } |