Pagini recente » Cod sursa (job #2963207) | Cod sursa (job #2961815) | Cod sursa (job #2833361) | Cod sursa (job #3206793) | Cod sursa (job #2962117)
#include <bits/stdc++.h>
using namespace std;
int n;
vector<string> siruri;
vector<string> corecte;
vector<bool> ok;
int ant[20][1 << 20];
int dp[20][500000], cost[20][20];
ofstream fout("adn.out");
int KMP(string &str1, string &str2) {
vector<int> kmp = vector<int>(str1.size() + str2.size() + 5, 0);
string s;
s += '#' + str1;
int l2, l1 = (int) s.size() - 1, cont = 0;
s += '&' + str2;
l2 = (int) s.size() - 1;
kmp[1] = 0;
for (int i = 2; i <= l2; ++i) {
int k = i - 1;
while (k && s[i] != s[kmp[k] + 1])
k = kmp[k];
if (s[i] == s[kmp[k] + 1])
kmp[i] = kmp[k] + 1;
else kmp[i] = 0;
if (kmp[i] == l1)
cont++;
}
//returnam lungimea daca e continut
if (cont >= 1)
return l1;
//returnam nr de caractere comune
return kmp[l2];
}
void Hamilton_cost_maxim() {
int total = (1 << n) - 1;
for (int mask = 0; mask <= total; mask++) {
for (int sf = 0; sf < n; sf++) {
if ((mask & (1 << sf)) == 0)
continue;
for (int anterior = 0; anterior < n; anterior++) {
if (anterior == sf)
continue;
if ((mask & (1 << anterior)) == 0)
continue;
int c = dp[anterior][mask ^ (1 << sf)] + cost[anterior][sf];
if (dp[sf][mask] <= c) {
dp[sf][mask] = c;
ant[sf][mask] = anterior;
}
}
}
}
int current = 0;
for (int i = 0; i < n; i++) {
if (dp[current][total] < dp[i][total]) {
current = i;
}
}
vector<int> drum;
int mask = total;
while (mask != 0) {
drum.push_back(current);
int ant_mask = mask ^ (1 << current);
int nod_ant = ant[current][mask];
current = nod_ant;
mask = ant_mask;
}
reverse(drum.begin(), drum.end());
int skip_next = 0;
for (int i = 0; i < n; i++) {
int node = drum[i];
string s = corecte[node].substr(skip_next);
fout << s;
if (i != n - 1) {
skip_next = cost[node][drum[i + 1]];
}
}
}
int main() {
ifstream fin("adn.in");
fin >> n;
ok.resize(n + 1, true);
for (int i = 0; i < n; ++i) {
string a;
fin >> a;
siruri.push_back(a);
}
for (int i = 0; i <= n; ++i)
for (int j = 0; j <= n; ++j)
cost[i][j] = -1;
for (int i = 0; i < n; ++i)
for (int j = 0; j < n; ++j)
if (i != j) {
int comune = KMP(siruri[i], siruri[j]);
if (comune == siruri[i].size()) {
ok[i] = false;
}
}
for (int i = 0; i < n; ++i) {
if (ok[i]) {
corecte.push_back(siruri[i]);
}
}
n = (int) corecte.size();
for (int i = 0; i < n; ++i)
for (int j = 0; j < n; ++j)
if (i != j) {
int comune = KMP(corecte[j], corecte[i]);
cost[i][j] = comune;
}
Hamilton_cost_maxim();
return 0;
}