T2

#include <bits/stdc++.h>
using namespace std;

namespace myb {
	
	const int N = 20;
	
	int n;
	string s[N];
	int len[N];
	int nxt[20005];
	int f[1 << N][N];
	void solve() {
		for (int i = 0;i < n;i++) {
			cin >> s[i];
		}
		sort(s, s + n, [] (string &a, string &b) {
			return a.size() > b.size();
		});
		int m = -1;
		for (int i = 0;i < n;i++) {
			int siz = s[i].size();
			nxt[0] = -1;
			for (int j = 1, k = -1;j < siz;j++) {
				while (k != -1 && s[i][k + 1] != s[i][j]) k = nxt[k];
				if (s[i][k + 1] == s[i][j]) k++;
				nxt[j] = k;
			}
			int flag = 1;
			for (int j = 0;j <= m;j++) {
				int l = len[j];
				for (int a = 0, b = -1;a <= l;a++) {
					while (b != -1 && s[i][b + 1] != s[j][a]) b = nxt[b];
					if (s[i][b + 1] == s[j][a]) b++;
					if (b == siz) {
						flag = 0;
						break;
					}
//					cout << a << " " << b << "?\n";
				}
				if (!flag) break;
			}
//			cout << "\n";
			if (flag) {
				s[++m] = s[i];
				len[m] = s[i].size();
				cout << m << " " << s[m] << " " << len[m] << '\n';
			}
		}
		
		memset(f, 0x3f, sizeof f);
		for (int i = 0;i < m;i++) {
			f[1 << i][i] = len[i];
		}
		for (int i = 1;i < (1 << m + 1);i++) {
			vector<int> ok;
			for (int j = 0;j < m;j++) {
				if ((i >> j) & 1) ok.push_back(j);
			}
			for (int x : ok) {
				for (int y : ok) {
					if (x == y) continue;
					string s1 = s[x], s2 = s[y];
					int len1 = len[x], len2 = len[y];
					for (int t = 0;t < 4;t++) {
						if (t & 1) reverse(s1.begin(), s1.end());
						if ((t >> 1) & 1) reverse(s2.begin(), s2.end());
						string S = s1 + s2;
//						cout << x << "  " << y << " " << S << "\n";
						int siz = S.size();
						for (int j = 1, k = -1;j < siz;j++) {
							while (k && S[k + 1] != S[j]) k = nxt[k];
							if (S[k + 1] == S[j]) k++;
							nxt[j] = k;
						}
//						cout << nxt[siz - 1] << "?\n";
						
						f[i][x] = min(f[i][x], f[i ^ (1 << x)][y] + len1 - nxt[siz - 1]);
						if (t & 1) reverse(s1.begin(), s1.end());
						if ((t >> 1) & 1) reverse(s2.begin(), s2.end());
						cout << bitset<3>(i) << " " << x << " " << f[i][x] << "\n";
//						cout << f[i ^ (1 << x)][y] << " " << len1 - nxt[siz - 1] << "\n\n";
					}
				}
			}
		}
		int ans = 1e9;
		for (int i = 0;i < m;i++) {
			ans = min(ans, f[(1 << m) - 1][i]);
		}
		cout << ans << "\n";
	}
	void main() {
		cin >> n;
		while (n) {
			solve();
			cin >> n;
		}
	}
}

int main() {
	myb::main();
	return 0;
}
posted @ 2025-11-18 20:33  yanbinmu  阅读(3)  评论(0)    收藏  举报