// 2556. Uddered but not Herd
#include<cstdio>
#include<string>
#include<iostream>
#include<vector>
#include<map>
using namespace std;
int main()
{
string inp; // 输入串
cin>>inp;
vector<vector<int> > c; // 相邻字母出现的次数
vector<int> f; // 状压DP
map<char,int> letpair; // 离散化,字母与离散后编号的pair
// 对存在的字母进行标记
for(int i=0;i<inp.length();i++)
{
letpair[inp[i]]=1;
}
// 离散化编号(利用map的自动排序)
int i = 0, numofnum=0;
for(auto iter=letpair.begin();iter!=letpair.end();iter++,i++)
{
iter->second=i;
numofnum++;
}
// 动态数组resize
f.resize((1<<numofnum)+5);
c.resize(numofnum+5,vector<int>(numofnum+5));
// 预处理c数组(相邻字母出现的次数)
for(int i=0;i<inp.length()-1;i++)
{
c[letpair[inp[i]]][letpair[inp[i+1]]]++;
}
// 状压DP,status=状压后的选择情况(01串状压)
for(int status=0;status<(1<<numofnum);status++)
{
// x=当前选的字母,在status中必须已选
for(int x=0;x<numofnum;x++)
{
if((status&(1<<x))==0)continue; // 非已选,直接跳过
int tempf = f[status-(1<<x)];
// y=前面的字母,用于检测顺序,在status中必须已选
for(int y=0;y<numofnum;y++)
{
if((status&(1<<y))==0)continue; // 非已选,直接跳过
// 累加 tempf = f[status-(1<<x)] + sum(c[x][y])
// (不选x的情况下的status)
tempf+=c[x][y];
}
// 对f[st-x]+sum(c[x][y])取最小值
f[status]=min(f[status],tempf);
}
}
printf("%d",f[(1<<numofnum)-1]);
return 0;
}
样例输出0