Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <cstdio>
- #include <array>
- #define task "tests"
- using namespace std;
- using ll = long long;
- using ld = long double;
- const int N = 1 << 20 + 2;
- const int Inf = 1e9 + 7;
- int k, n;
- int a[N];
- int all;
- int par[N];
- int dp[N], g[N];
- array<int8_t, 22> tr[N];
- void Read(){
- cin >> k >> n;
- for(int i = 1; i <= n; ++i){
- string s;
- cin >> s;
- a[i] = 0;
- for(int j = 0; j < k; ++j)
- if(!(s[j] - '0'))
- a[i] |= 1 << j;
- ++g[a[i]];
- }
- }
- void Calculate_g(){
- all = (1 << k) - 1;
- for(int i = 0; i <= all; ++i)
- dp[i] = Inf,
- par[i] = -1;
- for(int j = 0; j < k; ++j)
- for(int i = 0; i < (1 << k); ++i)
- if(i & (1 << j))
- g[i] += g[i ^ (1 << j)];
- }
- void Trace(int v){
- if(par[v] == -1)
- return;
- Trace(par[v]);
- int vv = (v ^ par[v]), lv = 0;
- while(vv > 1){
- ++lv;
- vv >>= 1;
- }
- cout << lv + 1 << " ";
- }
- bool Check(int i, int j){
- for(int t = 1; t <= __builtin_popcount(j); ++t){
- if(tr[i][t] > tr[j][t])
- return true;
- if(tr[i][t] < tr[j][t])
- return false;
- }
- }
- void Solve(){
- dp[0] = 0;
- //cout << "***\n";
- for(int i = 1; i < (1 << k); ++i){
- for(int j = 0; j < k; ++j)
- if(i & (1 << j))
- if(dp[i] > dp[i ^ (1 << j)] + g[all ^ (i ^ (1 << j))]
- || (dp[i] == dp[i ^ (1 << j)] + g[all ^ (i ^ (1 << j))] && Check(i, i ^ (1 << j))) )
- {
- dp[i] = dp[i ^ (1 << j)] + g[all ^ (i ^ (1 << j))];
- par[i] = i ^ (1 << j);
- tr[i] = tr[i ^ (1 << j)];
- tr[i][__builtin_popcount(i)] = j;
- }
- }
- cout << dp[(1 << k) - 1] << "\n";
- for(int i = 1; i <= k; ++i)
- cout << tr[(1 << k) - 1][i] + 1 << " ";
- }
- main(){
- ios::sync_with_stdio(0);
- cin.tie(0);
- cout.tie(0); if(fopen(task".IN", "r"))
- freopen(task".IN", "r", stdin);
- int t;
- cin >> t;
- while(t--)
- Read(),
- Calculate_g(),
- Solve();
- }
Advertisement
Add Comment
Please, Sign In to add comment