Pagini recente » Cod sursa (job #1503595) | Cod sursa (job #1995906) | Cod sursa (job #3287034) | Cod sursa (job #1894883) | Cod sursa (job #867558)
Cod sursa(job #867558)
#include <fstream>
#include <string>
#include <algorithm>
#define isSet(a,b) ((a>>b) & 1)
using namespace std;
ifstream cin("adn.in");
ofstream cout("adn.out");
const int inf = int(1e9);
const int LMAX = 30005, NMAX = 18;
int a[NMAX][LMAX];
int disabled;
int N;
string s[NMAX], sol;
int P[NMAX][NMAX];
int dp[1<<NMAX][NMAX];
char who[1<<NMAX][NMAX];
void readData() {
cin>>N;
cin.get();
for(int i = 0;i < N;i++) {
getline(cin,s[i]);
}
}
void prefix(const string &str,int pat[LMAX]) {
int k = 0;
pat[0] = 0;
for(int i = 1;i < (int)str.size();i++) {
while(k > 0 && str[i] != str[k]) k = pat[k - 1];
if(str[i] == str[k]) k++;
pat[i] = k;
}
}
void match(const int &text,const int &pattern) {
int k = 0;
for(int i = 0;i < (int)s[text].size();i++) {
while(k > 0 && s[text][i] != s[pattern][k]) k = a[pattern][k - 1];
if(s[text][i] == s[pattern][k]) k++;
if(k == (int)s[pattern].size()) {
disabled |= (1<<pattern);
k = a[pattern][k - 1];
}
}
P[text][pattern] = k;
}
int memo(const int &state,const int &v) {
int &ret = dp[state][v];
if(ret != inf) return ret;
ret = ret - 1;
if((state & (state - 1)) == 0) {
return ret = (int)s[v].size();
}
for(int w = 0;w < N;w++) {
if(v == w || isSet(disabled,w) || isSet(state,w) == false) continue;
int cost = s[v].size() + memo(state ^ (1<<v),w) - P[w][v];
if(cost < ret) {
ret = cost;
who[state][v] = w;
}
}
return ret;
}
void buildSolution(int state,int v,int pos) {
while(state > 0) {
if(pos == -1) {
if((state & (state - 1)) == 0) {
state = 0;
} else {
int w = who[state][v];
pos = s[who[state][v]].size() - P[who[state][v]][v] - 1;
state ^= (1<<v);
v = w;
}
} else {
sol += s[v][pos--];
}
}
}
void solve() {
for(int i = 0;i < N;i++) {
prefix(s[i],a[i]);
}
for(int i = 0;i < N;i++) {
for(int j = 0;j < N;j++) {
if(i != j) {
match(i,j);
}
}
}
for(int i = 0;i < (1<<N);i++) {
for(int k = 0;k < N;k++) {
dp[i][k] = inf;
}
}
int notDisabled = ((1<<N) - 1) ^ disabled;
int ans = inf, bestNode = -1;
for(int i = 0;i < N;i++) {
if(isSet(notDisabled,i) && memo(notDisabled,i) < ans) {
ans = memo(notDisabled,i);
bestNode = i;
}
}
buildSolution(notDisabled,bestNode,s[bestNode].size() - 1);
reverse(sol.begin(),sol.end());
cout<<sol;
}
int main()
{
readData();
solve();
return 0;
}