萌新刚学 OI,求助一道水题 qwq
查看原帖
萌新刚学 OI,求助一道水题 qwq
298549
SIXIANG32楼主2023/5/2 12:34

如题

啊啊啊啊啊打炸了疯了啊啊啊啊啊

//SIXIANG
#include <iostream>
#include <algorithm> 
#include <cstring>
#define MAXN 100000
#define QWQ cout << "QWQ" << endl;
using namespace std;
struct node {
	string str, rev;
} Q[16 + 10], P[16 + 10];
bool cmp(node &x, node &y) {
	return x.str.size() < y.str.size();
}
bool del[16 + 10];
int f[20][(1 << 16) + 10][2];
void update(int &x, int y) {
	x = min(x, y);
}
int cost(string a, string b) {//a 在 b 前 
	int len1 = a.size();
	int len2 = b.size();
  	for(int i = 0; i < len1; i++) { // place b at position i
   		if(len2 + i <= len1) continue; // b cannot extend to the right of a
    	bool ok = true;
    	for(int j = 0; i + j < len1; j++)
      		if(a[i+j] != b[j]) {ok = false; break; }
    	if(ok) return len1 - i;
  	}
  	return 0;
}
int ct[20][20][2][2];
int init() {
	memset(del, 0, sizeof(del)); 
	int n; cin >> n;
	if(!n) return -1;
	for(int p = 0; p < n; p++) {
		cin >> Q[p].str;
		Q[p].rev = Q[p].str;
		reverse(Q[p].rev.begin(), Q[p].rev.end());
	}
	sort(Q, Q + n, cmp);
	
	for(int p = 0; p < n; p++)
		for(int i = p + 1; i < n; i++) {
			string s1 = Q[i].str, s2 = Q[p].str, s3 = Q[i].rev;
			if(s1.find(s2) != string::npos
			|| s3.find(s2) != string::npos) {
				del[p] = 1;
				break;
			}
		}
	int t = 0;
	for(int p = 0; p < n; p++)
		if(!del[p])
			P[t++] = Q[p];
	n = t;
	for(int p = 0; p < n; p++)
		Q[p] = P[p];
	
	memset(f, 0x3f, sizeof(f));
	const int inf = f[0][0][0];
	for(int p = 0; p < n; p++)
		f[p][(1 << p)][0] = f[p][(1 << p)][1] = Q[p].str.size();
	f[0][1][1] = inf;
	for(int i = 0; i < n; i++)
		for(int j = 0; j < n; j++) {
			ct[i][j][0][0] = cost(Q[i].str, Q[j].str);
			ct[i][j][0][1] = cost(Q[i].str, Q[j].rev);
			ct[i][j][1][0] = cost(Q[i].rev, Q[j].str);
			ct[i][j][1][1] = cost(Q[i].rev, Q[j].rev);
		}
	for(int S = 0; S < (1 << n); S++)
		for(int i = 0; i < n; i++)
			for(int j = 0; j < n; j++)
				if(i != j && ((S >> j) & 1) == 0 && ((S >> i) & 1) == 1) {
					if(f[i][S][0] != inf) {
						int len = Q[j].str.size(); 
						update(f[j][S + (1 << j)][0], f[i][S][0] + len - ct[i][j][0][0]);
						update(f[j][S + (1 << j)][1], f[i][S][0] + len - ct[i][j][0][1]);
					}
					if(f[i][S][1] != inf) {
						int len = Q[j].str.size();
						update(f[j][S + (1 << j)][0], f[i][S][1] + len - ct[i][j][1][0]);
						update(f[j][S + (1 << j)][1], f[i][S][1] + len - ct[i][j][1][1]);
					}
				}
 
 	int minn = 1145141919;	
	if(n == 1) {
		int len = Q[1].str.size();
		int c1 = cost(Q[1].str, Q[1].str);
		int c2 = cost(Q[1].rev, Q[1].rev);
		int ans = min(len - c1, len - c2);
		cout << max(ans, 2) << endl;
		return 0;
	}
	for(int p = 1; p < n; p++) {//有环,规定 1 是第一个 
		int len = Q[p].str.size();
		minn = min(minn, f[p][(1 << n) - 1][0] - cost(Q[p].str, Q[0].str));
		minn = min(minn, f[p][(1 << n) - 1][1] - cost(Q[p].rev, Q[0].str)); 
	}
	if(minn <= 1) cout << 2 << endl;
	else cout << minn << endl;
	return 114514; 
}
int main() {
//	freopen("read.txt", "r", stdin);
//	freopen("write.txt", "w", stdout);
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
	while(1) if(init() < 0) return 0;
}
2023/5/2 12:34
加载中...