Pagini recente » Cod sursa (job #2848268) | Cod sursa (job #1411515) | Cod sursa (job #2023858) | Cod sursa (job #13591) | Cod sursa (job #2119541)
#include <fstream>
#include <vector>
using namespace std;
ifstream cin ("adn.in");
ofstream cout ("adn.out");
string s[20];
unsigned long long H[20][30100];
unsigned long long put[30100];
const unsigned long long base = 197;
int lung[20][20];
bool ignore[20];
const int max_mask = 1 << 18;
int dp[max_mask][20];
int n;
void make_H(){
for (int i=1; i<=n; i++){
for (int j=1; j<=(int)s[i].size(); j++){
H[i][j] = H[i][j-1];
H[i][j] *= base;
H[i][j] += s[i][j-1];
}
}
put[0] = 1;
for (int i=1; i<=30000; i++){
put[i] = put[i-1] * base;
}
}
void make_lung(){
for (int i=1; i<=n; i++){
if (ignore[i]){
continue;
}
for (int j=1; j<=n; j++){
if (i == j){
continue;
}
if (ignore[j]){
continue;
}
if (s[i].size() <= s[j].size()){
for (int k=0; k + s[i].size() <= s[j].size(); k++){
unsigned long long H1 = H[i][s[i].size()];
unsigned long long H2 = H[j][k + s[i].size()] - H[j][k] * put[s[i].size()];
if (H1 == H2){
ignore[i] = true;
break;
}
}
}
if (ignore[i]){
continue;
}
int same = 0;
for (int k = max(0 , (int)s[i].size() - (int)s[j].size()); k < s[i].size(); k++){
unsigned long long H1 = H[i][s[i].size()] - H[i][k] * put[s[i].size() - k];
unsigned long long H2 = H[j][s[i].size() - k];
if (H1 == H2){
same = (int)s[i].size() - k;
break;
}
}
lung[i][j] = (int)s[j].size() - same;
}
}
}
vector <char> ans;
int main() {
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
cin>>n;
for (int i=1; i<=n; i++){
cin>>s[i];
}
make_H();
make_lung();
for (int mask = 1; mask < (1 << n); mask++){
for (int bit = 0; bit < n; bit++){
dp[mask][bit] = 1e9;
}
}
for (int i=0; i<n; i++){
if (ignore[i+1]){
continue;
}
dp[(1 << i)][i] = (int)s[i+1].size();
}
for (int mask = 0; mask < (1 << n); mask++){
for (int last = 0; last < n; last++){
if (ignore[last+1]){
continue;
}
if (!((1 << last) & mask)){
continue;
}
for (int bit = 0; bit < n; bit++){
if (ignore[bit+1]){
continue;
}
if ((1 << bit) & mask){
continue;
}
int now_mask = mask ^ (1 << bit);
dp[now_mask][bit] = min (dp[now_mask][bit] , dp[mask][last] + lung[last+1][bit+1]);
}
}
}
int mask_fin = (1 << n) - 1;
for (int i=0; i<n; i++){
if (ignore[i+1]){
mask_fin ^= (1 << i);
}
}
int l = 1e9;
int last = 0;
for (int i=0; i<n; i++){
if (ignore[i+1]){
continue;
}
if (l > dp[mask_fin][i]){
l = dp[mask_fin][i];
last = i;
}
}
while (mask_fin){
mask_fin ^= (1 << last);
for (int i=0; i<n; i++){
if ((1 << i) & mask_fin){
if (dp[mask_fin][i] == l - lung[i+1][last+1]){
for (int j = (int)s[last+1].size() - 1; j >= (int)s[last+1].size() - lung[i+1][last+1]; j--){
ans.push_back(s[last+1][j]);
}
l -= lung[i+1][last+1];
last = i;
break;
}
}
}
}
for (int i=(int)s[last+1].size() - 1; i>=0; i--){
ans.push_back(s[last+1][i]);
}
for (int i=(int)ans.size()-1; i>=0; i--){
cout<<ans[i];
}
return 0;
}