#pragma GCC optimize("O3") //#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx") #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef LOCAL #define eprintf(...) fprintf(stderr,__VA_ARGS__) clock_t __my_start_clock = clock(); #else #define eprintf(...) #endif #define TIMESTAMP(x) eprintf("["#x"] Time : %.3lf s.\n", (clock() - __my_start_clock)*1.0/CLOCKS_PER_SEC) #define TIMESTAMPf(x,...) eprintf("[" x "] Time : %.3lf s.\n", __VA_ARGS__, (clock() - __my_start_clock)*1.0/CLOCKS_PER_SEC) #define db(x) cerr << #x << " = " << x << endl #define db2(x, y) cerr << "(" << #x << ", " << #y << ") = (" << x << ", " << y << ")\n"; #define db3(x, y, z) cerr << "(" << #x << ", " << #y << ", " << #z << ") = (" << x << ", " << y << ", " << z << ")\n" #define dbv(a) cerr << #a << " = "; for (auto xxxx: a) cerr << xxxx << " "; cerr << endl using namespace std; #ifdef LOCAL static struct __timestamper { string what; __timestamper(const char* what) : what(what){}; __timestamper(const string& what) : what(what){}; ~__timestamper(){ TIMESTAMPf("%s", what.data()); } } __TIMESTAMPER("end"); #else struct __timestamper {}; #endif namespace solve { int n; int half, half_mask; int ans, mans; int mask, cost; // vector>> dp; int dp[30][2][1 << 15]; vector> a; template inline void rec() { rec(); int cur = n - left; int old_cost = cost; cost += dp[cur][0][mask & half_mask]; cost += dp[cur][1][mask >> half]; cost += a[cur][cur]; mask ^= 1 << cur; rec(); mask ^= 1 << cur; cost = old_cost; } template<> inline void rec<0>() { if (ans < cost) { ans = cost; mans = mask; } } template void prerec() { if (left > n) { prerec(); } else { rec(); } } template<> void prerec<0>() { assert(0); } string solve(string s, vector> _a) { a = _a; n = s.length(); half = (n + 1) / 2; half_mask = (1 << half) - 1; // dp.assign(n, vector>(2)); for (int i = 0; i < n; i++) { for (int j = 0; j < 2; j++) { int len = j == 0 ? half : n - half; int start = j == 0 ? 0 : half; // dp[i][j].assign(1 << len, 0); for (int mask = 0; mask < (1 << len); mask++) { dp[i][j][mask] = 0; for (int t = 0; t < len; t++) { if (mask & (1 << t)) { dp[i][j][mask] += a[start + t][i]; } } } } } ans = -2e9; mans = -1; mask = 0; cost = 0; prerec<30>(); string res; for (int i = 0; i < n; i++) if (mans & (1 << i)) res += s[i]; return res; } } // namespace solve vector> gen(mt19937 &rnd, int n) { const int C = 1e6; vector> a(n, vector(n)); for (int i = 0; i < n; i++) { for (int j = i; j < n; j++) { a[i][j] = rnd() % (C + C + 1) - C; } } return a; } void test() { int n = 30; mt19937 rnd; auto a = gen(rnd, n); solve::solve(string(n, 'a'), a); exit(0); } string slow(string s, vector> a) { int n = s.length(); int ans = -2e9; string sans; for (int mask = 0; mask < (1 << n); mask++) { int cur = 0; for (int i = 0; i < n; i++) if (mask & (1 << i)) { for (int j = i; j < n; j++) if (mask & (1 << j)) { cur += a[i][j]; } } if (ans < cur) { ans = cur; sans = ""; for (int i = 0; i < n; i++) if (mask & (1 << i)) sans += s[i]; } } return sans; } void stress() { for (int it = 4;; it++) { mt19937 rnd(it); if (it % 1000 == 0) db(it); int n = rnd() % 10 + 1; string s; for (int i = 0; i < n; i++) s += 'a' + i; auto a = gen(rnd, n); auto f = [&](string res) { vector h(n); for (int i = 0; i < n; i++) h[i] = std::find(res.begin(), res.end(), s[i]) != res.end(); int score = 0; for (int i = 0; i < n; i++) for (int j = i; j < n; j++) if (h[i] && h[j]) score += a[i][j]; return score; }; auto ans1 = solve::solve(s, a); auto ans2 = slow(s, a); if (f(ans1) != f(ans2)) { db(it); db(s); for (auto v : a) { dbv(v); } db2(ans1, ans2); db2(f(ans1), f(ans2)); exit(0); } } } int main() { #ifdef LOCAL freopen("in", "r", stdin); test(); // stress(); #endif string s; cin >> s; int n = s.length(); vector> a(n, vector(n)); for (int i = 0; i < n; i++) { for (int j = i; j < n; j++) { cin >> a[i][j]; } } auto ans = solve::solve(s, a); cout << ans.length() << endl << ans << endl; return 0; }