Advertisement
Guest User

Untitled

a guest
Jul 28th, 2017
58
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.88 KB | None | 0 0
  1. #include <cstdio>
  2. #include <string>
  3. #include <vector>
  4. #include <algorithm>
  5. #include <cstring>
  6. #include <cassert>
  7. #include <iostream>
  8.  
  9. using namespace std;
  10.  
  11. vector<string> v;
  12.  
  13. int memo[30][100000], prizes[30], l;
  14.  
  15. vector<int> ans;
  16. void endgame(int mask) {
  17.     for(int i = 0; i < l; i++)
  18.         if((mask & (1<<i)) == 0)
  19.             ans.push_back(i+1);
  20. }
  21.  
  22. int doit(int size, int first, int last, int mask, bool track) {
  23.     int& ret = memo[size][first];
  24.     if(!track) {
  25.         if(ret != -1) return ret;
  26.         ret = 0x3f3f3f3f;
  27.     }
  28.  
  29.     int lo, hi;
  30.     if(((1<<(v[first][size]-1)) & mask) == 0) {
  31.         int mask2 = mask | (1<<(v[first][size]-1));
  32.  
  33.         lo = first; hi = last+1;
  34.         while(lo < hi) {
  35.             int mid = (lo + hi)/2;
  36.             if(v[mid].size() == size+1 && v[mid][size] == v[first][size])
  37.                 lo = mid+1;
  38.             else
  39.                 hi = mid;
  40.         }
  41.  
  42.         int prize = (lo-first) * prizes[size];
  43.         int first2 = lo;
  44.  
  45.         if(first2 <= last && v[first2][size] == v[first][size]) {
  46.             // Skipped over 0 -> v[first2][size+1]-1. Any holes?
  47.             int msk = ((1<<(v[first2][size+1]-1))-1) & ~mask2;
  48.  
  49.             if(msk) {
  50.                 if(track && ret == prize) {
  51.                     ans.push_back(v[first][size]);
  52.                     int lst = __builtin_ffs(msk)-1;
  53.                     ans.push_back(lst+1);
  54.                     endgame(mask2 | (1<<lst));
  55.                     return ret;
  56.                 }
  57.                 ret = min(ret, prize);
  58.             }
  59.  
  60.             // Nope, no holes, adjust last correctly
  61.             lo = first2, hi = last;
  62.             while(lo < hi) {
  63.                 int mid = (lo+hi+1)/2;
  64.                 if(v[mid][size] != v[first][size])
  65.                     hi = mid-1;
  66.                 else
  67.                     lo = mid;
  68.             }
  69.  
  70.             if(track && prize + doit(size+1, first2, lo, mask2, false) == ret) {
  71.                 ans.push_back(v[first][size]);
  72.                 doit(size+1, first2, lo, mask2, true);
  73.                 return ret;
  74.             }
  75.             ret = min(ret, prize + doit(size+1, first2, lo, mask2, false));
  76.         } else {
  77.             if(track && prize == ret) {
  78.                 ans.push_back(v[first][size]);
  79.                 endgame(mask2);
  80.                 return ret;
  81.             }
  82.             ret = min(ret, prize);
  83.         }
  84.     }
  85.  
  86.     lo = first; hi = last;
  87.     if(v[first][size] != v[last][size]) {
  88.         while(lo < hi) {
  89.             int mid = (lo+hi)/2;
  90.             if(v[mid][size] > v[first][size])
  91.                 hi = mid;
  92.             else
  93.                 lo = mid+1;
  94.         }
  95.  
  96.         // Skipped over v[first][size]+1 -> v[lo][size]-1, check for holes
  97.         int msk = ((1<<(v[lo][size]-1))-1) &
  98.             (~((1<<v[first][size])-1)) & ~mask;
  99.         if(msk) {
  100.             if(track) {
  101.                 int lst = __builtin_ffs(msk)-1;
  102.                 ans.push_back(lst+1);
  103.                 endgame(mask | (1<<lst));
  104.                 return 0;
  105.             }
  106.             return ret = 0;
  107.         }
  108.  
  109.         if(track && doit(size, lo, last, mask, false) == ret) {
  110.             doit(size, lo, last, mask, true);
  111.             return ret;
  112.         }
  113.         ret = min(ret, doit(size, lo, last, mask, false));
  114.     } else {
  115.         // Skipped over v[last][size]+1 -> l-1. Holes?
  116.         int msk = ((1<<l)-1) & (~((1<<v[last][size])-1)) & ~mask;
  117.         if(msk) {
  118.             if(track) {
  119.                 int lst = __builtin_ffs(msk)-1;
  120.                 ans.push_back(lst+1);
  121.                 endgame(mask | (1<<lst));
  122.                 return 0;
  123.             }
  124.             return ret = 0;
  125.         }
  126.     }
  127.  
  128.     return ret;
  129. }
  130.  
  131. int main() {
  132.     int t;
  133.     scanf("%d", &t);
  134.  
  135.     for(int i = 0; i < t; i++) {
  136.         v.clear();
  137.  
  138.         int n;
  139.         scanf("%d %d", &l, &n);
  140.         for(int j = 0; j < l; j++)
  141.             scanf("%d", &prizes[j]);
  142.  
  143.         for(int j = 0; j < n; j++) {
  144.             int sz;
  145.             scanf("%d", &sz);
  146.  
  147.             string s(sz, (char)1);
  148.             int tmp;
  149.             for(int k = 0; k < sz; k++) {
  150.                 scanf("%d", &tmp);
  151.                 s[k] = tmp;
  152.             }
  153.  
  154.             v.push_back(s);
  155.         }
  156.  
  157.         sort(v.begin(), v.end());
  158.  
  159.         memset(memo, -1, sizeof memo);
  160.         doit(0, 0, v.size() - 1, 0, false);
  161.  
  162.         ans.clear();
  163.         doit(0, 0, v.size() - 1, 0, true);
  164.  
  165.         int cst = 0;
  166.         for(int i = 0; i < n; i++) {
  167.             bool ok = true;
  168.             for(int j = 0; j < v[i].size(); j++)
  169.                 if(v[i][j] != ans[j])
  170.                     ok = false;
  171.             if(ok) cst += prizes[v[i].size()-1];
  172.         }
  173.  
  174.         assert(doit(0, 0, v.size() - 1, 0, false) == cst);
  175.  
  176.         printf("%d", ans[0]);
  177.         for(int i = 1; i < l; i++)
  178.             printf(" %d", ans[i]);
  179.         printf("\n");
  180.     }
  181. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement