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*/
阅读全文
1 0
- UVA1204FunGame
- linux中的高级网络配置
- 编程实现查找两个字符串的最大公共子串 示例:"aocdfe"和"pmcdfa"最大公共子串为"cfd"
- D
- TwoSum
- 3.1. Cross-validation: 评估 estimator 的性能
- UVA1204FunGame
- C语言入门:求一批整数中出现最多的数字
- 8月11日总结
- if __name__ == '__main__'到底干了什么?(关键词:Python、__name__、__main__)
- 笨办法学 Python · 续 第五部分:文本解析
- 2017 8.11
- SPOJ 7001 Visible Lattice Points (莫比乌斯反演+分块)
- stdlib.h包含的函数
- 8.11