uva1204

#include<iostream>
#include<algorithm>
#include<math.h>
#include<string.h>
#include<stdio.h>
#include<string>
#include<vector>
#include<queue>
#include<map>
#include<sstream>
#include<cassert>
using namespace std;
#define REP(i,n) for(int i=0;i<n;i++)
const int maxn = 16+5;
const int maxlen = 100 + 5;

struct Item {
	string s, rev;
	bool operator<(const Item &rhs) {
		return s.length() < rhs.s.length();
	}
};
int n;
string s[maxn][2];
int len[maxn];
int overlap[maxn][maxn][2][2];
int calc_overlap(const string&a, const string &b) {
	int n1 = a.length();
	int n2 = b.length();
	for (int i = 1; i < n1; i++) {//從i開始往後判斷a是否與b相等
		if (n2 + i <= n1)continue;
		bool ok = true;
		for (int j = 0; i + j < n1; j++) {
			if (a[i + j] != b[j]) {
				ok = false; break;
			}
		}
		if (ok)return n1 = i;
	}
	return 0;
}
void init() {
	Item tmp[maxn];
	REP(i, n) {
		cin >> tmp[i].s;
		tmp[i].rev = tmp[i].s;
		reverse(tmp[i].rev.begin(), tmp[i].rev.end());
	}
	int n2 = 0;
	//預處理,將包含於其他字符串的字串刪除
	sort(tmp, tmp + n);
	REP(i, n) {
		bool need = true;
		for (int j = i + 1; j < n; j++) {
			if (tmp[j].s.find(tmp[i].s) != string::npos || tmp[j].rev.find(tmp[i].s) != string::npos) {
				need = false; break;
			}
		}
		if (need) {//如果不是重複就加入數組
			s[n2][0] = tmp[i].s;
			s[n2][1] = tmp[i].rev;
			len[n2] = tmp[i].s.length();
			n2++;
		}
	}
	n = n2;
	REP(i, n)REP(j, n)REP(x, 2)REP(y, 2)
		overlap[i][j][x][y] = calc_overlap(s[i][x],s[j][y]);

}
int d[1 << maxn][maxn][2];
inline void update(int &x, int v) {
	if (x < 0 || v < x)x = v;
}
void solve() {
	memset(d, -1, sizeof(d));
	d[1][0][0] = len[0];
	int full = (1 << n) - 1;
	for (int s = 1; s < full; s++) {
		REP(i,n)REP(x,2)//枚舉尾部
			if (d[s][i][x] >= 0) {
				for (int j = 1; j < n; j++) {
					if (!(s&(1 << j))) {//枚舉新加人的字串
						REP(y, 2)update(d[s | 1 << j][j][y], d[s][i][x] + len[j] - overlap[i][j][x][y]);//更新最小值
					}
				}
			}
	}
	int ans = -1;
	REP(i,n)
		REP(x, 2) {
		if (d[full][i][x] < 0)continue;
		update(ans, d[full][i][x] - overlap[i][0][x][0]);//len[0]一開始就加過了
	}
	if (ans <= 1)ans = 2;
	cout << ans << endl;
}
int main() {
	
	while (cin >> n && n) {
		init();
		solve();
	}
	return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章