Pagini recente » Cod sursa (job #2425641) | Cod sursa (job #2528943) | Cod sursa (job #2485376) | Cod sursa (job #2458354) | Cod sursa (job #1556658)
#include <fstream>
#include <cstring>
#include <numeric>
using namespace std;
const int MAX_N = 18;
const int MAX_LEN = 30000;
int D[1 << MAX_N][MAX_N];
int F[1 << MAX_N][MAX_N];
int cost[MAX_N][MAX_N]; // cost[i][j] = costul daca j vine dupa i
char s[MAX_N][MAX_LEN + 1];
char tmp[2 * MAX_LEN + 2];
int Z[2 * MAX_LEN + 2];
int N;
int ZAlg(int A, int B)
{
int N = strlen(s[A]), M = strlen(s[B]);
memcpy(tmp, s[B], M);
tmp[M] = '$';
memcpy(tmp + M + 1, s[A], N);
int lBox = 0, rBox = 0;
for (int i = 1; i <= N + M; i++)
{
if (i <= rBox)
Z[i] = min(Z[i - lBox], rBox - i + 1);
else
Z[i] = 0;
while (tmp[Z[i]] == tmp[i + Z[i]])
Z[i]++;
if (i + Z[i] - 1 > rBox)
{
rBox = i + Z[i] - 1;
lBox = i;
}
}
int Q = 0;
for (int i = 0; i < N; i++)
Q = max(Q, Z[i + M + 1]);
return M - Q;
}
int hamilton(int mask, int prev)
{
if (D[mask][prev])
return D[mask][prev];
if (mask == (1 << N) - 1)
return 0;
D[mask][prev] = numeric_limits <int> :: max();
for (int i = 0; i < N; i++)
{
if (((mask >> i) & 1) == false)
{
int C = hamilton(mask | (1 << i), i) + cost[prev][i];
if (D[mask][prev] > C)
{
D[mask][prev] = C;
F[mask][prev] = i;
}
}
}
return D[mask][prev];
}
int main()
{
ifstream in("adn.in");
ofstream out("adn.out");
in >> N;
for (int i = 0; i < N; i++)
in >> s[i];
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
if (i != j)
cost[i][j] = ZAlg(i, j);
int minCost = numeric_limits <int> :: max(), node;
for (int i = 0; i < N; i++)
{
for (int j = 0; j < (1 << N); j++)
for (int t = 0; t < N; t++)
D[j][t] = 0;
int C = strlen(s[i]) + hamilton(1 << i, i);
if (minCost > C)
{
minCost = C;
node = i;
}
}
int mask = 1 << node;
out << s[node];
while (mask != (1 << N) - 1)
{
int prev = node;
node = F[mask][node];
out << (s[node] + strlen(s[node]) - cost[prev][node]);
mask |= (1 << node);
}
out << '\n';
return 0;
}