#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. 做新时代的奋斗者!(好吧,我还没弄出python的编译环境)

    Pictures: 今日分来的补记来嘞: Game 1:Guess the number. Python包含许多内建的函数,有些函数存在于称为模块的单独的程序中,可以使用import语句把它们的模块导 ...

  2. MP3 文件格式解析

    目录: 1.mp3 文件简介 2.ID3 tag id3 v2 3.音频帧 要注意的地方 4.参考 5.一个临时解析方法 一.MP3文件简介 MP3(mpeg-1 Ⅲ 或者 mpeg-2 Ⅲ)是一种将 ...

  3. Flask 教程 第二十一章:用户通知

    本文翻译自The Flask Mega-Tutorial Part XXI: User Notifications 这是Flask Mega-Tutorial系列的第二十一章,我将添加一个私有消息功能 ...

  4. selenium通过cookies直接免密登录

    前提知识: 1.webdriver中提供了操作cookie的相关方法: get_cookies()                    获得cookie信息 add_cookie(cookie_di ...

  5. toString()和toLocaleString()方法有什么区别和联系

    toString()和toLocaleString()有什么区别 偶然之间用到这两个方法 然后在数字转换成字符串的时候,并没有感觉这两个方法有什么区别,如下: 1 2 3 4 5 6 7 8 var  ...

  6. jmeter plugin manager安装插件

    https://jmeter-plugins.org/wiki/PluginsManager/ 以websocket 插件为例 先安装plugin manger 第二步:打开jmetre  optio ...

  7. JS高级---工厂模式创建对象和自定义构造函数创建对象的区别

    创建对象:工厂模式和自定义构造函数的区别 共同点: 都是函数, 都可以创建对象, 都可以传入参数   区别:   工厂模式: 函数名是小写 有new, 有返回值 new之后的对象是当前的对象 直接调用 ...

  8. Building Ethereum private chain on CentOS

    golang安装 yum install golang 查看版本 go version 安装以太坊源代码 Building Geth (command line client) Clone the r ...

  9. 吴裕雄 python 机器学习——模型选择损失函数模型

    from sklearn.metrics import zero_one_loss,log_loss def test_zero_one_loss(): y_true=[1,1,1,1,1,0,0,0 ...

  10. [BPNN]BP神经网络实现

    BP神经网络实现 以3层网络为例,Python实现: 1.代码框架 主要函数: Init函数:设定InputLayer nodes.HiddenLayer nodes.OutputLayer node ...