#define HAVE_STRUCT_TIMESPEC
#include<bits/stdc++.h>
using namespace std;
char s[100005];
int pos[(1<<20)+5];//pos[i]表示i=1<<j时的j
int cnt[35][35];//cnt[i][j]表示s[i]=i,s[i+1]=j的移动数量
int g[25][(1<<20)+5];//g[i][S],i不属于S表示s[i]=i,s[i+1]∈S的移动数量
int h[(1<<20)+5];//h[S]表示所有s[i]∈S,s[i+1]不属于S的移动数量
int dp[(1<<20)+5];
int main(){
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
int n,m;
cin>>n>>m;
cin>>s+1;
for(int i=1;i<n;++i){
int gg=s[i]-'a';
int tt=s[i+1]-'a';
++cnt[gg][tt];
++cnt[tt][gg];
}
for(int i=0;i<m;++i)
pos[1<<i]=i;
for(int i=0;i<m;++i)
for(int j=1;j<(1<<m)-1;++j)
if(!((j>>i)&1))
g[i][j]=g[i][j-(j&-j)]+cnt[i][pos[j&-j]];//i和j不在同一集合内,g[i][j]表示在集合j中加入字母i的话会增加多少次移动
for(int i=1;i<(1<<m)-1;++i)
for(int j=0;j<m;++j)
if((i>>j)&1)
h[i]+=g[j][i^((1<<m)-1)];//j和i在同一集合内,枚举i内的所有元素j,求和得到集合i的补集中加依次入集合i中所有元素会增加多少次移动
for(int i=1;i<(1<<m);++i)
dp[i]=1e9+7;
dp[0]=0;
for(int i=0;i<(1<<m)-1;++i)//i上为1的位表明该字母在键盘上的位置已经确定,键盘上从左到右的顺序取决于dp过程中先后被加入进dp的h,随着更新最小值,从左到右顺序也被暗中替换为更小值的顺序(最左边字母进入时因为只有一个字母所以不会产生移动,它的贡献是最初的dp[i],i中只有一位1,dp[i]=0)
for(int j=0;j<m;++j)
if(!((i>>j)&1))
dp[i^(1<<j)]=min(dp[i^(1<<j)],h[i]+dp[i]);//求dp[i^(1<<j)]相当于在dp[i]已有的键盘顺序上最右端加入字母j,此时所有已经在键盘上的字母和剩下所有还不在键盘上的字母相邻的话移动距离都会增加一格,所以要加上h[i],即i上所有为1的位j的g[j][k]之和,k是i的补集也就是还不在键盘上的那些字母
//其实如果不为了复杂度降低一个m的话,可能更容易理解一些,这道题的关键在于每次向已经排列好的键盘右端加入一个新字母,此时依次将所有已经在键盘上的字母和与其相邻的所有还未在键盘上的字母个数相加,尽可能复杂度低的计算出这些集合与集合之间的相邻个数。
cout<<dp[(1<<m)-1];
return 0;
}

Educational Codeforces Round 74 (Rated for Div. 2)E(状压DP,降低一个m复杂度做法含有集合思维)的更多相关文章

  1. Educational Codeforces Round 74 (Rated for Div. 2) D. AB-string

    链接: https://codeforces.com/contest/1238/problem/D 题意: The string t1t2-tk is good if each letter of t ...

  2. Educational Codeforces Round 74 (Rated for Div. 2) C. Standard Free2play

    链接: https://codeforces.com/contest/1238/problem/C 题意: You are playing a game where your character sh ...

  3. Educational Codeforces Round 74 (Rated for Div. 2) B. Kill 'Em All

    链接: https://codeforces.com/contest/1238/problem/B 题意: Ivan plays an old action game called Heretic. ...

  4. Educational Codeforces Round 74 (Rated for Div. 2) A. Prime Subtraction

    链接: https://codeforces.com/contest/1238/problem/A 题意: You are given two integers x and y (it is guar ...

  5. Educational Codeforces Round 74 (Rated for Div. 2)

    传送门 A. Prime Subtraction 判断一下是否相差为\(1\)即可. B. Kill 'Em All 随便搞搞. C. Standard Free2play 题意: 现在有一个高度为\ ...

  6. Educational Codeforces Round 74 (Rated for Div. 2)【A,B,C【贪心】,D【正难则反的思想】】

    A. Prime Subtractiontime limit per test2 secondsmemory limit per test256 megabytesinputstandard inpu ...

  7. Educational Codeforces Round 74 (Rated for Div. 2)补题

    慢慢来. 题目册 题目 A B C D E F G 状态 √ √ √ √ × ∅ ∅ //√,×,∅ 想法 A. Prime Subtraction res tp A 题意:给定\(x,y(x> ...

  8. Educational Codeforces Round 61 (Rated for Div. 2)F(区间DP,思维,枚举)

    #include<bits/stdc++.h>typedef long long ll;const int inf=0x3f3f3f3f;using namespace std;char ...

  9. Educational Codeforces Round 76 (Rated for Div. 2) E. The Contest dp

    E. The Contest A team of three programmers is going to play a contest. The contest consists of

随机推荐

  1. 题解 P3951 小凯的疑惑

    P3951 小凯的疑惑 数论极菜的小萌新我刚看这题时看不懂exgcd做法的题解,后来在网上找到了一篇博客,感觉代码和推导都更加清新易懂,于是在它的基础上写了题解qwq 分析 两数互质,且有无限个,想到 ...

  2. Python 字符串格式化操作 - format方法

    建议使用format()方法 字符串操作 对于 %, 官方以及给出这种格式化操作已经过时,在 Python 的未来版本中可能会消失. 在新代码中使用新的字符串格式.因此推荐大家使用format()来替 ...

  3. 【做题笔记】P2871 [USACO07DEC]手链Charm Bracelet

    就是 01 背包.大意:给您 \(T\) 个空间大小的限制,有 \(M\) 个物品,第 \(i\) 件物品的重量为 \(c_i\) ,价值为 \(w_i\) .要求挑选一些物品,使得总空间不超过 \( ...

  4. h5 datalist标签获取值

    今天使用datalist标签时,想要获得选中的值,发现使用datalist标签上的val()输出结果一直都是空的 后面改用配套的input获得值 代码如下 <!DOCTYPE html> ...

  5. 吴裕雄 python 机器学习——集成学习随机森林RandomForestClassifier分类模型

    import numpy as np import matplotlib.pyplot as plt from sklearn import datasets,ensemble from sklear ...

  6. React 实现input输入框的防抖和节流

    1.为什么使用防抖和节流对于频繁触发的事件 比如keydown keyup事件 当频繁点击时候 会多次触发事件 页面出现卡顿 影响性能 2.函数防抖(debounce):间隔时间内只执行一次   函数 ...

  7. Linux 内核内存池

    内核中经常进行内存的分配和释放.为了便于数据的频繁分配和回收,通常建立一个空闲链表——内存池.当不使用的已分配的内存时,将其放入内存池中,而不是直接释放掉. Linux内核提供了slab层来管理内存的 ...

  8. CSS学习(3)样式表

    如何插入样式表 插入样式表的方法有三种: 外部样式表(External style sheet) 内部样式表(Internal style sheet) 内联样式(Inline style) 外部样式 ...

  9. oracle 唯独测试视图

    --建立用户分配权限 create user groper identified by groper / grant connect,resource to groper / grant create ...

  10. 关于excuteQuery与execute()

    excuteQuery是查询语句,如果是更新或者插入或报错,换成execute()就好了