Pagini recente » Cod sursa (job #3292022) | Cod sursa (job #1224780) | Cod sursa (job #3285893) | Cod sursa (job #3290265) | Cod sursa (job #3154071)
#include <fstream>
#include <string>
#include <vector>
using namespace std;
ifstream in ("adn.in");
ofstream out ("adn.out");
const int max_conf = (1 << 20) + 5, max_size = 3e4 + 7, INF = 2e9 + 1;
string s[20];
int match[20][20], p[2 * max_size], nm[20], ans[20];
bool ok[20];
pair <int, int> dp[262300][20];
vector <int> conf[20];
bool kmp (int x, int y)
{
string a = s[y] + '$' + s[x];
int q = 0;
for (int i = 1; i < a.size(); i++)
{
while (q > 0 && a[q] != a[i])
{
q = p[q - 1];
}
if (a[q] == a[i])
{
q++;
}
p[i] = q;
if (p[i] == s[y].size())
{
return true;
}
}
match[x][y] = s[y].size() - p[a.size() - 1];
return false;
}
int preproc (int n)
{
int x = 0;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
if (i == j)
{
continue;
}
ok[j] |= kmp(i, j);
}
}
for (int i = 0; i < n; i++)
{
if (!ok[i])
{
nm[x++] = i;
}
}
return x;
}
int main ()
{
int n;
in >> n;
for (int i = 0; i < n; i++)
{
in >> s[i];
}
n = preproc(n);
for (int i = 0; i < (1 << n); i++)
{
conf[__builtin_popcount(i)].push_back(i);
}
for (int i = 0; i < n; i++)
{
dp[(1 << i)][i].first = s[nm[i]].size();
dp[(1 << i)][i].second = -1;
}
for (int i = 2; i <= n; i++)
{
for (auto f : conf[i])
{
for (int j = 0; j < n; j++)
{
if ((f & (1 << j)) != 0)
{
dp[f][j] = {INF, 0};
for (int k = 0; k < n; k++)
{
if (((f ^ (1 << j)) & (1 << k)) != 0)
{
dp[f][j] = min(dp[f][j], {dp[(f ^ (1 << j))][k].first + match[nm[k]][nm[j]], k});
}
}
}
}
}
}
int ind = 0;
for (int i = 1; i < n; i++)
{
if (dp[(1 << n) - 1][i].first < dp[(1 << n) - 1][ind].first)
{
ind = i;
}
}
int mask = (1 << n) - 1, rez = 0;
while (ind > -1)
{
ans[++rez] = ind;
int aux = ind;
ind = dp[mask][ind].second;
mask ^= (1 << aux);
}
out << s[nm[ans[rez]]];
for (int i = rez - 1; i > 0; i--)
{
int x = match[nm[ans[i + 1]]][nm[ans[i]]];
for (int j = s[nm[ans[i]]].size() - x; j < s[nm[ans[i]]].size(); j++)
{
out << s[nm[ans[i]]][j];
}
}
in.close();
out.close();
return 0;
}