题意:你要给字母表的前 个字母排列,定义每对字母的距离: ,给定一个长度为 的字符串 ,求
解法:设 为 二进制下 的数量,设 为字母 和字母 在 中相邻的次数,我们逐位来填字母,设 为前 位填的字母集合为 ,每个已填的字母对其他所有字母在前 位的贡献的总和的最小值为 ,假设我们接下来在 位又填了一个字母使得状态变成了 ,对于 , ,显然又增加一次距离的贡献,那么 , 复杂度即可解决这题
//预处理可以降低一个m
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 5;
int a[21], w[21][21], dp[1 << 20];
char s[maxn];
int main() {
int n, m;
scanf("%d%d%s", &n, &m, s + 1);
for (int i = 2; i <= n; i++) {
int u = s[i] - 'a';
int v = s[i - 1] - 'a';
w[u][v]++;
w[v][u]++;
}
int N = 1 << m;
for (int i = 1; i < N; i++) {
dp[i] = 1e9;
for (int j = 0; (1 << j) <= i; j++)
if (i >> j & 1)
dp[i] = min(dp[i], dp[i ^ (1 << j)]);
for (int j = 0; (1 << j) <= i; j++)
if (i >> j & 1)
for (int k = 0; k < m; k++)
if (!(i >> k & 1))
dp[i] += w[j][k];
}
printf("%d\n", dp[N - 1]);
}