Pagini recente » Cod sursa (job #1155197) | Cod sursa (job #1522924) | Cod sursa (job #2142001) | Cod sursa (job #577632) | Cod sursa (job #2964790)
#include <fstream>
#include <cstring>
#include <vector>
#include <string>
using namespace std;
ifstream in("adn.in");
ofstream out("adn.out");
const int NMAX = 18;
const int INF = 1000000;
string s, cuv[NMAX];
vector<int> pre(0,INF);
bool inclus[1 + NMAX];
vector<pair<int, int>> graf[NMAX];
int dp[1 << NMAX][NMAX];
pair<int, int> last[1 << NMAX][NMAX];
void kmp(int i, int j)
{
fill(pre.begin(), pre.end(), pre.size());
s = ' ' + cuv[i] + '$' + cuv[j];
int pi = 0;
for (int l = 2; l < s.size(); l++)
{
while (pi > 0 && s[l] != s[pi + 1])
pi = pre[pi];
if (s[l] == s[pi + 1])
pi++;
pre[l] = pi;
if (pi == cuv[i].size())
inclus[i] = true;
}
graf[i].emplace_back(make_pair(j, cuv[i].size() - pre[s.size() - 1]));
}
string makeSol(int msBit, int nod)
{
if (msBit == 0)
return "";
string s = makeSol(msBit - (1 << nod), last[msBit][nod].first);
for (int i = cuv[nod].size() - last[msBit][nod].second; i < cuv[nod].size(); i++)
s += cuv[nod][i];
return s;
}
int main()
{
int n;
in >> n;
for (int i = 0; i < n; i++)
in >> cuv[i];
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
if (i != j)
kmp(i, j);
for (int msBit = 0; msBit < (1 << n); msBit++)
for (int nod = 0; nod < n; nod++)
dp[msBit][nod] = INF;
for (int nod = 0; nod < n; nod++)
{
dp[1 << nod][nod] = cuv[nod].size();
last[1 << nod][nod] = make_pair(-1, cuv[nod].size());
}
for (int msBit = 0; msBit < (1 << n); msBit++)
for (int nod = 0; nod < n; nod++)
if (!inclus[nod] && (msBit & (1 << nod)) != 0)
for (auto& vecin : graf[nod])
if (!inclus[vecin.first] && (msBit & (1 << vecin.first)) != 0)
if (dp[msBit][nod] > dp[msBit - (1 << nod)][vecin.first] + vecin.second)
{
dp[msBit][nod] = dp[msBit - (1 << nod)][vecin.first] + vecin.second;
last[msBit][nod] = vecin;
}
int sol = INF, solMask = (1<<n) - 1, solNod = -1;
for (int i = 0; i < n; i++)
if (inclus[i])
solMask -= (1 << i);
for (int i = 0; i < n; i++)
if (!inclus[i] && sol > dp[solMask][i])
{
sol = min(sol, dp[solMask][i]);
solNod = i;
}
out << makeSol(solMask, solNod) << '\n';
return 0;
}