UVALive 6088 Approximate Sorting constructor, uvalive6088
Question link: Click the open link
Question:
Given A 01 matrix of n * n
Let's run the example =
4
0111
0000
0100
0110
0123
| ____
0 | 0111
1 | 0000
2 | 0100
3 | 0110
Use 0-n-1 to construct a random sequence:
Example: 1230
We calculate the 1230 weight:
Int ans = 0;
For a single digit 0, we can find 0th rows: 123 rows before 0111,0, And the number before 0 is, ans + = a [0] [1], ans + = a [0] [2], ans + = a [0] [3]
For 10-10-3 rows, we can search for the first row: 0110,3, where the first number is 12, ans + = a [3] [1], ans + = a [3] [2].
Ans = 6
Q:
Construct such a sequence to minimize ans. If there are multiple such sequences, the Lexicographic Order of the output sequence is the smallest.
#include <cstdio>#include <iostream>#include <string>#include <map>#include <cstring>#include <algorithm>#include <vector>using namespace std;const int Inf = 1e9;typedef long long ll;const int N = 18;const int S = 1 << N;int d[S], one[S];int w[N], n, mx;int out[N], dep;map<int, int> id;int dp(int s) {if (~d[s])return d[s];d[s] = Inf;int i, to, x = s;while (x>0) {to = (x&(x-1)) ^ x;i = id[to];d[s] = min(d[s], dp(s^(1<<i)) + one[w[i]&s]);x = x^to;}return d[s];}void dfs(int dep, int cur, int g) {if (dep == N) {one[cur] = g;} else {dfs(dep+1, cur*2+1, g+1);dfs(dep+1, cur*2, g);}}void path(int s) {if (s != 0) {for (int i = 0; i < n; ++i)if (s >> i & 1) {if (dp(s^(1 << i)) + one[w[i]&s] == dp(s) ) {out[dep++] = i;path(s^(1 <<i));return ;}}}}char s[N];void work() {memset(w, 0, sizeof w);for (int i = 0; i < n; ++i) {scanf("%s", s);for (int j = 0; j < n; ++j)if (s[j] == '1' && j != i)w[j] |= 1 << i;}mx = (1 << n) - 1;memset(d, -1, sizeof d);d[0] = 0;int ans = dp(mx);dep = 0;path(mx);for (int i = 0; i < dep; ++i) {if (i > 0)putchar(' ');printf("%d", out[i]);}puts("");printf("%d\n", ans);}int main() {dfs(0, 0, 0);for (int i = 0; i < N; ++i)id[1 << i] = i;while (~scanf("%d", &n)) {if (0 == n)break;work();}return 0;}