#include<cstdio> #include<algorithm> #include<functional> const int N = 24; const int Nsubsets = 1 << N; const int M = 100; struct SubsetData{ char minBackpacks; int minContentOfLast; SubsetData():minBackpacks(N + 1), minContentOfLast(0){}; } DP[Nsubsets]; int itemMasses[N]; int maxLoads[M]; int singletons[N]; void printSet(int s, int n){ printf("{"); bool first = true; for(int i = 0; i < n - 1; i++) if(s & singletons[i]){ printf(first ? "%d" : ", %d", i); first = false; } printf("}"); } int main(){ int n, m; scanf("%d%d", &n, &m); for(int i = 0; i < n; i++){ scanf("%d", &itemMasses[i]); singletons[i] = 1 << i; } std::sort(itemMasses, itemMasses + n); for(int i = 0; i < m; i++) scanf("%d", &maxLoads[i]); std::sort(maxLoads, maxLoads + m, std::greater<int>()); for(int i = 0; i != n; ++i){ if(itemMasses[i] > maxLoads[0]){ printf("NIE\n"); return 0; } DP[singletons[i]].minBackpacks = 1; DP[singletons[i]].minContentOfLast = itemMasses[i]; } for(int s = 1; s < (1 << n) - 1; ++s){ //printSet(s, n); //printf("\t - %d %d\n", DP[s].minBackpacks, DP[s].minContentOfLast); int i = 0; int newContent; for(; i != n && (newContent = DP[s].minContentOfLast + itemMasses[i]) <= maxLoads[DP[s].minBackpacks - 1]; ++i){ if(!(s & singletons[i])){ int si = s | singletons[i]; if(DP[s].minBackpacks < DP[si].minBackpacks){ DP[si].minBackpacks = DP[s].minBackpacks; DP[si].minContentOfLast = newContent; } if(DP[s].minBackpacks == DP[si].minBackpacks && newContent < DP[si].minContentOfLast) DP[si].minContentOfLast = newContent; } } for(; i != n && (newContent = itemMasses[i]) <= maxLoads[DP[s].minBackpacks]; ++i){ if(!(s & singletons[i])){ int si = s | singletons[i]; if(DP[s].minBackpacks + 1 < DP[si].minBackpacks){ DP[si].minBackpacks = DP[s].minBackpacks + 1; DP[si].minContentOfLast = newContent; } if(DP[s].minBackpacks + 1 == DP[si].minBackpacks && newContent < DP[si].minContentOfLast) DP[si].minContentOfLast = newContent; } } } if(DP[(1 << n) - 1].minBackpacks > n) printf("NIE\n"); else printf("%d\n", DP[(1 << n) - 1].minBackpacks); }
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 | #include<cstdio> #include<algorithm> #include<functional> const int N = 24; const int Nsubsets = 1 << N; const int M = 100; struct SubsetData{ char minBackpacks; int minContentOfLast; SubsetData():minBackpacks(N + 1), minContentOfLast(0){}; } DP[Nsubsets]; int itemMasses[N]; int maxLoads[M]; int singletons[N]; void printSet(int s, int n){ printf("{"); bool first = true; for(int i = 0; i < n - 1; i++) if(s & singletons[i]){ printf(first ? "%d" : ", %d", i); first = false; } printf("}"); } int main(){ int n, m; scanf("%d%d", &n, &m); for(int i = 0; i < n; i++){ scanf("%d", &itemMasses[i]); singletons[i] = 1 << i; } std::sort(itemMasses, itemMasses + n); for(int i = 0; i < m; i++) scanf("%d", &maxLoads[i]); std::sort(maxLoads, maxLoads + m, std::greater<int>()); for(int i = 0; i != n; ++i){ if(itemMasses[i] > maxLoads[0]){ printf("NIE\n"); return 0; } DP[singletons[i]].minBackpacks = 1; DP[singletons[i]].minContentOfLast = itemMasses[i]; } for(int s = 1; s < (1 << n) - 1; ++s){ //printSet(s, n); //printf("\t - %d %d\n", DP[s].minBackpacks, DP[s].minContentOfLast); int i = 0; int newContent; for(; i != n && (newContent = DP[s].minContentOfLast + itemMasses[i]) <= maxLoads[DP[s].minBackpacks - 1]; ++i){ if(!(s & singletons[i])){ int si = s | singletons[i]; if(DP[s].minBackpacks < DP[si].minBackpacks){ DP[si].minBackpacks = DP[s].minBackpacks; DP[si].minContentOfLast = newContent; } if(DP[s].minBackpacks == DP[si].minBackpacks && newContent < DP[si].minContentOfLast) DP[si].minContentOfLast = newContent; } } for(; i != n && (newContent = itemMasses[i]) <= maxLoads[DP[s].minBackpacks]; ++i){ if(!(s & singletons[i])){ int si = s | singletons[i]; if(DP[s].minBackpacks + 1 < DP[si].minBackpacks){ DP[si].minBackpacks = DP[s].minBackpacks + 1; DP[si].minContentOfLast = newContent; } if(DP[s].minBackpacks + 1 == DP[si].minBackpacks && newContent < DP[si].minContentOfLast) DP[si].minContentOfLast = newContent; } } } if(DP[(1 << n) - 1].minBackpacks > n) printf("NIE\n"); else printf("%d\n", DP[(1 << n) - 1].minBackpacks); } |