#include <iostream> #include <cstdio> #include <algorithm> #include <vector> using namespace std; int n, m; vector <long long> ile[25]; pair <long long,int> wilu[17000000]; long long rzecz[25]; long long udz[107]; long long pot[25]; int roz[25]; int it; int stanek; int stanek2; int bag; int bag2; long long wolne; long long wolne2; void liczaj(int odl, long long stan, int zap) { if (odl==n-1) { ile[zap].push_back(stan); return; } liczaj(odl+1, stan, zap); liczaj(odl+1, stan+pot[odl+1], zap+1); } void czyn(long long liczba) { for (int i=n-1; i>=0; i--) { roz[i]=0; if (liczba>=pot[i]) { roz[i]=1; liczba-=pot[i]; } } } bool mniej(long long a, long long b) { return a>b; } int main() { pot[0]=1; for (int i=1; i<=24; i++) { pot[i]=2*pot[i-1]; } scanf("%d%d", &n, &m); for (int i=0; i<n; i++) { scanf("%lld", &rzecz[i]); } for (int i=1; i<=m; i++) { scanf("%lld", &udz[i]); } sort(rzecz, rzecz+n, mniej); sort(udz+1, udz+1+m, mniej); liczaj(0, 0, 0); liczaj(0, 1, 1); for (int i=1; i<=pot[n]; i++) { wilu[i].first=-1; wilu[i].second=1007; } for (int i=0; i<n; i++) { for (int j=0; j<ile[i].size(); j++) { czyn(ile[i][j]); for (int k=0; k<n; k++) { stanek=ile[i][j]; if (!roz[k] && wilu[stanek].second<1000) { stanek2=stanek+pot[k]; bag=wilu[stanek].second; bag2=wilu[stanek2].second; wolne=wilu[stanek].first; wolne2=wilu[stanek2].first; if (wolne<rzecz[k] && bag<m && udz[bag+1]>=rzecz[k]) { if (bag2>bag+1 || (bag2==bag+1 && wolne2<udz[bag+1]-rzecz[k])) { wilu[stanek2].second=bag+1; wilu[stanek2].first=udz[bag+1]-rzecz[k]; } } else if (wolne>=rzecz[k]) { if (bag2>bag || (bag2==bag && wolne2<wolne-rzecz[k])) { wilu[stanek2].second=bag; wilu[stanek2].first=wolne-rzecz[k]; } } } } } } if (wilu[pot[n]-1].second<1000) printf("%d", wilu[pot[n]-1].second); else printf("NIE"); 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 | #include <iostream> #include <cstdio> #include <algorithm> #include <vector> using namespace std; int n, m; vector <long long> ile[25]; pair <long long,int> wilu[17000000]; long long rzecz[25]; long long udz[107]; long long pot[25]; int roz[25]; int it; int stanek; int stanek2; int bag; int bag2; long long wolne; long long wolne2; void liczaj(int odl, long long stan, int zap) { if (odl==n-1) { ile[zap].push_back(stan); return; } liczaj(odl+1, stan, zap); liczaj(odl+1, stan+pot[odl+1], zap+1); } void czyn(long long liczba) { for (int i=n-1; i>=0; i--) { roz[i]=0; if (liczba>=pot[i]) { roz[i]=1; liczba-=pot[i]; } } } bool mniej(long long a, long long b) { return a>b; } int main() { pot[0]=1; for (int i=1; i<=24; i++) { pot[i]=2*pot[i-1]; } scanf("%d%d", &n, &m); for (int i=0; i<n; i++) { scanf("%lld", &rzecz[i]); } for (int i=1; i<=m; i++) { scanf("%lld", &udz[i]); } sort(rzecz, rzecz+n, mniej); sort(udz+1, udz+1+m, mniej); liczaj(0, 0, 0); liczaj(0, 1, 1); for (int i=1; i<=pot[n]; i++) { wilu[i].first=-1; wilu[i].second=1007; } for (int i=0; i<n; i++) { for (int j=0; j<ile[i].size(); j++) { czyn(ile[i][j]); for (int k=0; k<n; k++) { stanek=ile[i][j]; if (!roz[k] && wilu[stanek].second<1000) { stanek2=stanek+pot[k]; bag=wilu[stanek].second; bag2=wilu[stanek2].second; wolne=wilu[stanek].first; wolne2=wilu[stanek2].first; if (wolne<rzecz[k] && bag<m && udz[bag+1]>=rzecz[k]) { if (bag2>bag+1 || (bag2==bag+1 && wolne2<udz[bag+1]-rzecz[k])) { wilu[stanek2].second=bag+1; wilu[stanek2].first=udz[bag+1]-rzecz[k]; } } else if (wolne>=rzecz[k]) { if (bag2>bag || (bag2==bag && wolne2<wolne-rzecz[k])) { wilu[stanek2].second=bag; wilu[stanek2].first=wolne-rzecz[k]; } } } } } } if (wilu[pot[n]-1].second<1000) printf("%d", wilu[pot[n]-1].second); else printf("NIE"); return 0; } |