Pagini recente » Cod sursa (job #3333975) | Diferente pentru problema/cbinteractiv intre reviziile 9 si 8 | Cod sursa (job #3327751) | Monitorul de evaluare | Cod sursa (job #3333718)
#include <bits/stdc++.h>
using namespace std;
string s[20];
int c[20][20];
bool included(string &s1, string &s2)
{
return s2.find(s1) != string::npos;
}
bool deleteString(int i, int j)
{
if(s[i].length() <= s[j].length())
{
if(included(s[i], s[j]))
return 1;
}
//else if(included(s[j], s[i]))
// return 1;
return 0;
}
string s3 = "";
int calc(string &s1, string &s2, string &s3)
{
unordered_set<int> s;
long long b = 137, mod = 1e9 + 7, nr = 0, p = 1;
for(int i = s1.length() - 1; i >= 0; i --)
nr = nr + (s1[i] - 'A' + 1) * p, nr %= mod, p *= b, p %= mod, s.insert(nr);
nr = 0;
int maxx = 0;
for(int i = 0; i < s2.length(); i ++)
{
nr = nr * b % mod + s2[i] - 'A' + 1, nr %= mod;
if(s.find(nr) != s.end())
maxx = i + 1;
}
if(s3 != "")
{
for(int i = maxx; i < s2.length(); i ++)
s3 += s2[i];
}
return s2.length() - maxx;
}
int dp[18][18][(1 << 18) + 5], n;
short t[18][18][(1 << 18) + 6];
int main()
{
ifstream f("adn.in");
ofstream g("adn.out");
f >> n;
for(int i = 0; i < n; i ++)
f >> s[i];
for(int i = 0; i < n; i ++)
for(int j = 0; j < n; j ++)
if(i != j)
if(deleteString(i, j))
{
for(int p = i; p < n - 1; p ++)
s[p] = s[p + 1];
n --;
i --;
break;
}
for(int i = 0; i < n; i ++)
for(int j = 0; j < n; j ++)
c[i][j] = calc(s[i], s[j], s3);
for(int i = 0; i < n; i ++)
for(int j = 0; j < n; j ++)
for(int p = 0; p < (1 << n); p ++)
dp[i][j][p] = 1e9;
for(int i = 0; i < n; i ++)
dp[i][i][(1 << i)] = s[i].length();
for(int start = 0; start < n; start ++)
{
for(int mask = 1; mask < (1 << n); mask ++)
{
for(int i = 0; i < n; i ++)
if(mask & (1 << i))
{
int prev = mask ^ (1 << i);
for(int j = 0; j < n; j ++)
if(prev & (1 << j)){
if(dp[start][j][prev] + c[j][i] <= dp[start][i][mask])
dp[start][i][mask] = min(dp[start][i][mask], dp[start][j][prev] + c[j][i]),
t[start][i][mask] = j;
}
}
}
}
int minn = 1e9, pozi, pozj, mask = (1 << n) - 1;
for(int i = 0; i < n; i ++)
for(int j = 0; j < n; j ++){
if(dp[i][j][mask] < minn)
minn = min(minn, dp[i][j][mask]), pozi = i, pozj = j;
}
vector<int> rez;
rez.push_back(pozj);
while(mask != (1 << pozi))
{
rez.push_back(t[pozi][pozj][mask]);
int aux = t[pozi][pozj][mask];
mask = mask ^ (1 << pozj);
pozj = aux;
}
string s_Rez = "";
reverse(rez.begin(), rez.end());
s_Rez = s[rez[0]];
for(int i = 1; i < n; i ++)
{
calc(s_Rez, s[rez[i]], s_Rez);
}
g << s_Rez;
//g << minn;
return 0;
}