UVA1204FunGame

来源:互联网 发布:麦克风测试软件汉化 编辑:程序博客网 时间:2024/06/16 23:44
//UVA1204FunGame#include<cstdio>#include<string>#include<cstring>#include<iostream>#include<algorithm>using namespace std;#define REP(i, n) for(int i = 0; i < (n); i++)const int maxn = 16;const int maxch = 100 + 10;int n;struct Item {string s, rev;bool operator < (const Item& rhs) const {    return s.length() < rhs.s.length(); }};string s[maxn][2];int over_cal(const string& s1, const string& s2) {int n1 = s1.length();int n2 = s2.length();////printf("n1 = %d, n2 = %d\n", n1, n2);for(int i = 1; i < n1; i++) {//i为s[i][x]串的一个位置,s[j][y]的头部从这个位置开始 if(i + n2 <= n1) continue;//此时有s[j][y]被s[i][x]完全包裹,由于被包含的部分早被预处理//这里的情况一定不符合重叠位置完全重合的要求bool ok = true;for(int j = 0; i + j < n1; j++) //循环终止条件保证s1重叠部分的遍历不出去 if(s1[i + j] != s2[j]) { ok = false; break;}if(ok) return n1 - i;}return 0;}int len[maxn], overlap[maxn][maxn][2][2];void Initial() {Item item[maxn]; REP(i, n) {cin >> item[i].s;    item[i].rev = item[i].s;reverse(item[i].rev.begin(), item[i].rev.end());}sort(item, item + n);int n2 = 0;REP(i, n) {bool ok = true;for(int j = i + 1; j < n; j++) {//     if(i != j) {     if(item[j].s.find(item[i].s) != string::npos || item[j].s.find(item[i].rev) != string::npos) {    ok = false; break;        }    } } if(ok) {s[n2][0] = item[i].s; s[n2][1] = item[i].rev;len[n2] = s[n2][0].length();n2++;//收集不被包含的串 }}n = n2;REP(i, n) REP(j, n) REP(x, 2) REP(y, 2) { overlap[i][j][x][y] = over_cal(s[i][x], s[j][y]);//    printf("overlap = %d\n", overlap[i][j][x][y]);} }int d[1 << maxn][maxn][2];void update(int& a, int tmp) {if(a < 0 || a > tmp) a = tmp;}void solve() {memset(d, -1, sizeof(d));d[1][0][0] = len[0];//将第一个位置设定成第一个串的正方向,便于成环时的处理const int full = (1 << n) - 1;for(int s = 1; s < full; s++) { REP(i, n) REP(x, 2) if(d[s][i][x] >= 0) //保证前一个状态是有效状态 REP(j, n) REP(y, 2)if(!(s & (1 << j))) update(d[s | (1 << j)][j][y], d[s][i][x] + len[j] - overlap[i][j][x][y]);//dp    } int ans = -1;    //printf("n = %d\n", n);REP(i, n) REP(x, 2) {if(d[full][i][x] >= 0)         update(ans, d[full][i][x] - overlap[i][0][x][0]);    }if(ans <= 1) ans = 2;    printf("%d\n", ans);}int main() {while(scanf("%d", &n) == 1 && n) {        Initial();solve();}return 0;;} /*2BGGGBBBGGGBBBG3BGGBBGBGGGGGBGB0*/