The ACM ICPC World Finals is a huge event! On 2018 the World Finals was at Beijing, China.
The chinese culture is way different than brazilian culture. They eat
(as they translated: "Bad fish chips")
and
(as they translated: "Sauteed chicken on the left")
Their traffic is crazy, with cars driving on the cycle path, motorcycles driving the wrong way or on the sidewalk. But, the weirdest of all, they use QR-codes for everything.
A QR-code is a square image, in this case a 21×2121×21 pixel matrix, that each pixel is either black or white. The code carries some information, usually an URL or a text, and can be read by almost all modern smartphones.
They use QR-codes so that people don't have to copy text all the time. They just have to open their smartphone's camera and the magic happens.
During a tour on Beijing, Lucas Santana, the Handsome, noticed that to visit some tourist places he needed to know the QR-code to buy the tickets for that place. Since he's a very smart guy, he decided to create a mobile application to draw the QR-codes, instead of searching for them.
The mobile application works as follow: it starts with a 21×2121×21 white pixel matrix. You can click any pixel to swap it's color from white to black or from black to white in 1 decisecond. Also, you can restart the application at any time to have an all white pixel matrix again, but it take aa deciseconds to do so. When you complete the QR-code, you can assume you can enter the tourist place.
Lucas knows the QR-code of nn places he wants to visit. He doesn't care about the order he visits the places, but, since he only have a few days left on China, he wants to spend the least time as possible drawing the QR-codes. Can you help him saying the minimum amount of deciseconds to draw all nn QR-codes, the order he should visit the places and when he should restart the application?
He will not visit the same place more than once. (Don't even try this. He will give you a wrong answer!).
The first line of input contains two integers, nn and aa (1≤n≤181≤n≤18, 1≤a≤501≤a≤50) — the number of places he wants to visit and the total time to restart the application.
The next lines contains the QR-codes of the places separated by empty lines. There will be nn QR-codes, each having 2121 lines of 2121 digits being 00 or 11. Digit 00 means a white pixel and 11 a black pixel.
Print the minimum amount of deciseconds to draw all QR-codes followed by at least nn lines and at most 2×n−12×n−1 lines. Each line should have one number between 11 and nn, meaning that he must visit the place ii, or one character "*" (without quotes), meaning that he must restart the application.
All numbers should be distinct.
If there are multiple answers, print any of them.
1 10
111111100101101111111
100000101101001000001
101110101100101011101
101110100101001011101
101110101000101011101
100000101001101000001
111111101010101111111
000000001111100000000
110100110110001110110
111101000100000110110
111110111110101101101
001110001011001101001
000111110010110100100
000000001001000100000
111111101110011110110
100000100011110001000
101110100101011100010
101110101111000010011
101110100100100110101
100000101010011100000
111111101101100010010
228
1
In sample case, he should just draw the only QR-code available and visit the place. The QR-code is:
思路:求出转移代价相当求一个哈密顿路,状压dp即可。
1 #include <iostream> 2 #include <fstream> 3 #include <sstream> 4 #include <cstdlib> 5 #include <cstdio> 6 #include <cmath> 7 #include <string> 8 #include <cstring> 9 #include <algorithm> 10 #include <queue> 11 #include <stack> 12 #include <vector> 13 #include <set> 14 #include <map> 15 #include <list> 16 #include <iomanip> 17 #include <cctype> 18 #include <cassert> 19 #include <bitset> 20 #include <ctime> 21 22 using namespace std; 23 24 #define pau system("pause") 25 #define ll long long 26 #define pii pair<int, int> 27 #define pb push_back 28 #define mp make_pair 29 #define clr(a, x) memset(a, x, sizeof(a)) 30 31 const double pi = acos(-1.0); 32 const int INF = 0x3f3f3f3f; 33 const int MOD = 1e9 + 7; 34 const double EPS = 1e-9; 35 36 /* 37 #include <ext/pb_ds/assoc_container.hpp> 38 #include <ext/pb_ds/tree_policy.hpp> 39 40 using namespace __gnu_pbds; 41 tree<pli, null_type, greater<pli>, rb_tree_tag, tree_order_statistics_node_update> T; 42 */ 43 44 int n, a; 45 char s[22][22][22]; 46 vector<int> e[22]; 47 struct Edge { 48 int v, w; 49 Edge () {} 50 Edge (int v, int w) : v(v), w(w) {} 51 }; 52 int cal(char a[22][22], char b[22][22]) { 53 int res = 0; 54 for (int i = 1; i <= 21; ++i) { 55 for (int j = 1; j <= 21; ++j) { 56 res += a[i][j] != b[i][j]; 57 } 58 } 59 return res; 60 } 61 int cal2(char a[22][22]) { 62 int dis = 0; 63 for (int i = 1; i <= 21; ++i) { 64 for (int j = 1; j <= 21; ++j) { 65 dis += a[i][j] - '0'; 66 } 67 } 68 return dis; 69 } 70 int dp[1 << 20][20], dis[22][22]; 71 pii pre[1 << 20][20]; 72 int main() { 73 scanf("%d%d", &n, &a); 74 for (int i = 1; i <= n; ++i) { 75 for (int j = 1; j <= 21; ++j) { 76 scanf("%s", s[i][j] + 1); 77 } 78 } 79 for (int i = 1; i <= n; ++i) { 80 for (int j = i + 1; j <= n; ++j) { 81 int d = cal(s[i], s[j]); 82 dis[i][j] = dis[j][i] = d; 83 } 84 } 85 for (int i = 1; i <= n; ++i) { 86 int d = cal2(s[i]); 87 dis[i][0] = dis[0][i] = d; 88 } 89 clr(dp, INF); 90 dp[0][0] = 0; 91 for (int i = 0; i < 1 << n; ++i) { 92 for (int j = n; ~j; --j) { 93 for (int k = 0; k <= n; ++k) { 94 if (!k) { 95 if (dp[i][k] > dp[i][j] + a) { 96 dp[i][k] = dp[i][j] + a; 97 pre[i][k] = pii(i, j); 98 } 99 } 100 else { 101 if (i & (1 << k - 1)) continue; 102 int x = i | (1 << k - 1); 103 if (dp[x][k] > dp[i][j] + dis[j][k]) { 104 dp[x][k] = dp[i][j] + dis[j][k]; 105 pre[x][k] = pii(i, j); 106 } 107 } 108 } 109 } 110 } 111 int ans = INF; 112 pii pp; 113 for (int i = 0; i <= n; ++i) { 114 if (ans > dp[(1 << n) - 1][i]) { 115 ans = dp[(1 << n) - 1][i]; 116 pp = pii((1 << n) - 1, i); 117 } 118 } 119 printf("%d\n", ans); 120 stack<pii> sta; 121 while (pp != pii(0, 0)) { 122 sta.push(pp); 123 int x = pp.first, y = pp.second; 124 pp = pre[x][y]; 125 } 126 while (sta.size()) { 127 pp = sta.top(); sta.pop(); 128 if (pp.second) { 129 printf("%d\n", pp.second); 130 } else { 131 puts("*"); 132 } 133 } 134 return 0; 135 }