Pagini recente » Cod sursa (job #2108651) | Cod sursa (job #433417) | Cod sursa (job #2221476) | Cod sursa (job #2214813) | Cod sursa (job #2975137)
#include <bits/stdc++.h>
using namespace std;
const int NMAX = 18;
const int SMAX = 30004;
const int INF = 4000004;
ifstream fin("adn.in");
ofstream fout("adn.out");
int n;
bool ok;
vector<string> adn;
vector<string> adn_rau;
int comun[NMAX][NMAX];
int lps[2 * SMAX];
pair<int, int> dp[NMAX][(1 << (NMAX - 1)) + 4];
int p[NMAX][(1 << (NMAX - 1)) + 4];
vector<int> cuv;
int kmp(string a, string b)
{
string s = b + '#' + a;
lps[0] = 0;
for (int i = 1; i < (int)s.size(); i++)
{
int j = lps[i - 1];
while (j > 0 && s[j] != s[i])
{
j = lps[j - 1];
}
if (s[j] == s[i])
{
j++;
}
lps[i] = j;
}
return lps[s.size() - 1];
}
bool kmp_find(string a, string b)
{
string s = a + '#' + b;
lps[0] = 0;
for (int i = 1; i < (int)s.size(); i++)
{
int j = lps[i - 1];
while (j > 0 && s[j] != s[i])
{
j = lps[j - 1];
}
if (s[j] == s[i])
{
j++;
}
lps[i] = j;
}
for (int i = (int)a.size() + 1; i < (int)s.size(); i++)
{
if (lps[i] == (int)a.size())
{
return true;
}
}
return false;
}
int main()
{
fin >> n;
for (int i = 0; i < n; i++)
{
string s;
fin >> s;
adn_rau.push_back(s);
}
for (int i = 0; i < n; i++)
{
ok = true;
for (int j = 0; j < n; j++)
{
if (i == j)
{
continue;
}
if (kmp_find(adn_rau[i], adn_rau[j]))
{
ok = false;
break;
}
}
if (ok)
{
adn.push_back(adn_rau[i]);
}
}
n = adn.size();
for (int i = 0; i < n; i++)
{
for (int j = i + 1; j < n; j++)
{
comun[i][j] = kmp(adn[i], adn[j]);
comun[j][i] = kmp(adn[j], adn[i]);
}
}
for (int i = 0; i < n; i++)
{
for (int conf = 0; conf < (1 << (n - 1)); conf++)
{
dp[i][conf] = {INF, INF};
}
}
for (int i = 1; i < n; i++)
{
dp[i][(1 << (i - 1))] = {(int)adn[0].size() + (int)adn[i].size() - comun[0][i], comun[0][i]};
p[i][(1 << (i - 1))] = 0;
}
for (int conf = 1; conf < (1 << (n - 1)); conf++)
{
for (int i = 1; i < n; i++)
{
if (conf & (1 << (i - 1)))
{
for (int j = 1; j < n; j++)
{
if (i == j)
{
continue;
}
if (conf & (1 << (j - 1)))
{
if (dp[j][conf].first > (dp[i][conf ^ (1 << (j - 1))].first + (int)adn[j].size() - comun[i][j]))
{
dp[j][conf].first = dp[i][conf ^ (1 << (j - 1))].first + (int)adn[j].size() - comun[i][j];
dp[j][conf].second = min(dp[i][conf ^ (1 << (j - 1))].second, comun[i][j]);
p[j][conf] = i;
}
}
}
}
}
}
for (int i = 1; i < n; i++)
{
dp[i][(1 << (n - 1)) - 1].first -= comun[i][0];
dp[i][(1 << (n - 1)) - 1].second = min(dp[i][(1 << (n - 1)) - 1].second, comun[i][0]);
}
int ind = 1;
for (int i = 2; i < n; i++)
{
if ((dp[i][(1 << (n - 1)) - 1].first + dp[i][(1 << (n - 1)) - 1].second) < (dp[ind][(1 << (n - 1)) - 1].first + dp[ind][(1 << (n - 1)) - 1].second))
{
ind = i;
}
}
int leg_min = dp[ind][(1 << (n - 1)) - 1].second;
cuv.push_back(0);
int conf = (1 << (n - 1)) - 1;
while (ind != 0)
{
cuv.push_back(ind);
int aux = ind;
ind = p[ind][conf];
conf = conf ^ (1 << (aux - 1));
}
cuv.push_back(0);
reverse(cuv.begin(), cuv.end());
int index;
for (int i = 0; i < (int)cuv.size() - 1; i++)
{
if (comun[cuv[i]][cuv[i + 1]] == leg_min)
{
index = i + 1;
}
}
int l = (int)cuv.size();
for (int i = 1; i < l; i++)
{
cuv.push_back(cuv[i]);
}
fout << adn[cuv[index]];
for (int i = index + 1; i <= index + l - 2; i++)
{
fout << adn[cuv[i]].substr(comun[cuv[i - 1]][cuv[i]], (int)adn[cuv[i]].size() - comun[cuv[i] - 1][cuv[i]]);
}
return 0;
}