#include<bits/stdc++.h>
using namespace std;
using i64 = long long;
//#define int i64
#define vi vector<int>
#define vvi vector<vi>
#define vb vector<bool>
#define se second
#define fi first
#define pii pair<int, int>
#define sz(x) (int)(x).size()
const int ABC = 26;
inline void solve(){
int n, mxsz = 0;
cin >> n;
vvi cnt(n, vi(ABC + 1));
vector<string> str(n);
for(int i = 0; i < n; i++){
string s;
cin >> s;
str[i] = s;
mxsz = max(mxsz, sz(s));
}
int idx = 0;
while(idx < mxsz){
char c = '#';
for(int i = 0; i < n; i++){
if(sz(str[i]) < idx) continue;
if(c != '#' && c != str[i][idx]){
c = '!';
break;
}
c = str[i][idx];
}
if(c == '!') break;
idx++;
}
for(int i = 0; i < n; i++){
reverse(str[i].begin(), str[i].end());
for(int j = 0; j < min(sz(str[i]), idx); j++){
str[i].pop_back();
}
reverse(str[i].begin(), str[i].end());
}
for(int i = 0; i < n; i++){
for(char &ch : str[i]){
cnt[i][ch - 'a']++;
}
cnt[i].back() = sz(str[i]);
}
vi dp(1 << n);
for(int mask = 1; mask < (1 << n); mask++){
// all same subtree (same common prefix)
vi mx(ABC, -1);
for(int bit = 0; bit < n; bit++){
if((mask >> bit) & 1){
for(int j = 0; j < ABC; j++){
if(mx[j] == -1 || cnt[bit][j] < mx[j]){
mx[j] = cnt[bit][j];
}
}
}
}
int common = accumulate(mx.begin(), mx.end(), 0);
dp[mask] = common;
for(int bit = 0; bit < n; bit++){
if((mask >> bit) & 1){
dp[mask] += cnt[bit].back() - common;
}
}
}
for(int mask = 1; mask < (1 << n); mask++){
for(int ss = mask; ss; ss = (ss - 1) & mask){
dp[mask] = min(dp[mask], dp[ss] + dp[mask ^ ss]);
}
}
cout << dp[(1 << n) - 1] + idx + 1 << "\n";
return;
}
signed main(){
ios_base::sync_with_stdio(false); cin.tie(0);
int t = 1;
//cin >> t;
while(t--){
solve();
}
return 0;
}
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |