Pagini recente » Cod sursa (job #1260882) | Istoria paginii utilizator/mariodinu | Cod sursa (job #1904938) | Cod sursa (job #325053) | Cod sursa (job #2922791)
#include <bits/stdc++.h>
using namespace std;
ifstream fin("adn.in");
ofstream fout("adn.out");
const int MaxN = 18;
const int MaxL = 30001;
string cuvinte[MaxN];
string s;
int prefix[5 + 2 * MaxL];
bool inclus[1 + MaxN];
int mat[MaxN][MaxN];
int dp[1 << MaxN][MaxN];
pair<int, int> last[1 << MaxN][MaxN]; /// last.first -> node, last.second -> len
void KMP(int cuv1, int cuv2)
{
memset(prefix, 0, sizeof(prefix));
s = ' ' + cuvinte[cuv1] + ' ' + cuvinte[cuv2];
int pi = 0;
for (int i = 2; i < s.size(); i++)
{
while (pi > 0 && s[i] != s[pi + 1])
pi = prefix[pi];
if (s[i] == s[pi + 1])
pi++;
prefix[i] = pi;
if (pi == cuvinte[cuv1].size())
inclus[cuv1] = true;
}
mat[cuv1][cuv2] = cuvinte[cuv1].size() - prefix[s.size() - 1];
}
string Solve(int bit, int nod)
{
if (bit == 0)
return "";
string s = Solve(bit - (1 << nod), last[bit][nod].first);
for (int i = cuvinte[nod].size() - last[bit][nod].second; i < cuvinte[nod].size(); i++)
s += cuvinte[nod][i];
return s;
}
int main()
{
int n;
fin >> n;
for (int i = 0; i < n; i++)
fin >> cuvinte[i];
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
if (i != j)
KMP(i, j);
for (int bit = 0; bit < (1 << n); bit++)
for (int nod = 0; nod < n; nod++)
dp[bit][nod] = 1e9;
for (int nod = 0; nod < n; nod++)
{
dp[1 << nod][nod] = cuvinte[nod].size();
last[1 << nod][nod] = make_pair(-1, cuvinte[nod].size());
}
for (int bit = 0; bit < (1 << n); bit++)
for (int nod = 0; nod < n; nod++)
if (!inclus[nod] && (bit & (1 << nod)) != 0)
for (int vec = 0; vec < n; vec++)
if (vec != nod && !inclus[vec] && (bit & (1 << vec)) != 0)
if (dp[bit][nod] > dp[bit - (1 << nod)][vec] + mat[nod][vec])
{
dp[bit][nod] = dp[bit - (1 << nod)][vec] + mat[nod][vec];
last[bit][nod] = {vec, mat[nod][vec]};
}
int sol_mask = (1 << n) - 1;
int node = -1;
int sol = 1e9;
for (int i = 0; i < n; i++)
if (inclus[i])
sol_mask -= (1 << i);
for (int i = 0; i < n; i++)
if (!inclus[i] && sol > dp[sol_mask][i])
{
node = i;
sol = min(sol, dp[sol_mask][i]);
}
fout << Solve(sol_mask, node) << "\n";
return 0;
}