Dang_Quan_10_Tin

D-Nhưng trâu hơn (Vẫn sai)

Jul 21st, 2020
346
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 1.81 KB | None | 0 0
  1. #include <iostream>
  2. #include <cstdio>
  3. #include <array>
  4. #define task "tests"
  5. using namespace std;
  6. using ll = long long;
  7. using ld = long double;
  8.  
  9. const int N = 1 << 20 + 2;
  10. const int Inf = 1e9 + 7;
  11. int k, n;
  12. int a[N];
  13. int all;
  14. int par[N];
  15. int dp[N], g[N];
  16. array<int8_t, 22> tr[N];
  17.  
  18. void Read(){
  19.     cin >> k >> n;
  20.     for(int i = 1; i <= n; ++i){
  21.         string s;
  22.         cin >> s;
  23.         a[i] = 0;
  24.         for(int j = 0; j < k; ++j)
  25.             if(!(s[j] - '0'))
  26.                 a[i] |= 1 << j;
  27.         ++g[a[i]];
  28.     }
  29. }
  30.  
  31. void Calculate_g(){
  32.     all = (1 << k) - 1;
  33.     for(int i = 0; i <= all; ++i)
  34.         dp[i] = Inf,
  35.         par[i] = -1;
  36.     for(int j = 0; j < k; ++j)
  37.         for(int i = 0; i < (1 << k); ++i)
  38.             if(i & (1 << j))
  39.                 g[i] += g[i ^ (1 << j)];
  40. }
  41.  
  42. void Trace(int v){
  43.     if(par[v] == -1)
  44.         return;
  45.     Trace(par[v]);
  46.     int vv = (v ^ par[v]), lv = 0;
  47.     while(vv > 1){
  48.         ++lv;
  49.         vv >>= 1;
  50.     }
  51.     cout << lv + 1 << " ";
  52. }
  53.  
  54. bool Check(int i, int j){
  55.     for(int t = 1; t <= __builtin_popcount(j); ++t){
  56.         if(tr[i][t] > tr[j][t])
  57.             return true;
  58.         if(tr[i][t] < tr[j][t])
  59.             return false;
  60.     }
  61. }
  62.  
  63. void Solve(){
  64.     dp[0] = 0;
  65.     //cout << "***\n";
  66.     for(int i = 1; i < (1 << k); ++i){
  67.         for(int j = 0; j < k; ++j)
  68.             if(i & (1 << j))
  69.                 if(dp[i] > dp[i ^ (1 << j)] + g[all ^ (i ^ (1 << j))]
  70.                     || (dp[i] == dp[i ^ (1 << j)] + g[all ^ (i ^ (1 << j))] && Check(i, i ^ (1 << j))) )
  71.                 {
  72.                     dp[i] = dp[i ^ (1 << j)] + g[all ^ (i ^ (1 << j))];
  73.                     par[i] = i ^ (1 << j);
  74.                     tr[i] = tr[i ^ (1 << j)];
  75.                     tr[i][__builtin_popcount(i)] = j;
  76.                 }
  77.     }
  78.     cout << dp[(1 << k) - 1] << "\n";
  79.     for(int i = 1; i <= k; ++i)
  80.         cout << tr[(1 << k) - 1][i] + 1 << " ";
  81. }
  82.  
  83. main(){
  84.     ios::sync_with_stdio(0);
  85.     cin.tie(0);
  86.     cout.tie(0); if(fopen(task".IN", "r"))
  87.     freopen(task".IN", "r", stdin);
  88.     int t;
  89.     cin >> t;
  90.     while(t--)
  91.         Read(),
  92.         Calculate_g(),
  93.         Solve();
  94. }
Advertisement
Add Comment
Please, Sign In to add comment