#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-调用自己写的函数

    在同一个目录下的话,直接在代码里添加即可,下面的例子. 同一个目录下有以下: aaa.py ccc.py ddd.py   想在ddd.py里用aaa.py里的函数,就在ddd.py里面开关位置添加 ...

  2. nomon+ pyNmonAnalyzer实现基于python的nmon监控性能数据可视化

    pip install pyNmonAnalyzer nnmon  for linux from sourceforge:https://sourceforge.net/projects/nmon/ ...

  3. 普及C组第二题(8.2)

    1340. [南海2009初中]jumpcow(牛跳) (Standard IO) 题目: John的奶牛们计划要跳到月亮上去.它们请魔法师配制了 P (1 <= P <=150,000) ...

  4. 查询 keystore文件的签名信息

    需要安装jdk 在安装 jdk的/bin文件夹下 keytool -v -list -keystore [keystore文件的路径]

  5. 树莓派学习之路-GPIO Zero

    原来用的都是RPi.GPIO模式开发,写程序 今天看到了GPIOZERO的资料,觉得这个API还是很好用的, 唯一的缺点就是官方资料是英文的,而且目前这方面的资料也不多, 所以开始写这篇博文,将自己学 ...

  6. 箭头函数 this指向问题

    1.为什么要用箭头函数 简洁 易用 固定this 指向(箭头函数在this定义时候生效) 2.箭头函数分析this指向 1.this指向调用函数的对象 情况1 var obj={ a:"1& ...

  7. java 面试架构篇

    1.非功能需求会考虑哪些? 可用性.扩展性.性能: 2.有没有遇到过建了索引反而变慢的情况? 3.从哪些角度去设计系统? 4.代码中使用过的设计模式?

  8. 输入两个正整数num1、num2,计算并输出它们的和、差、积、整数商和余数

    课本例题 /*输入两个正整数num1.num2,计算并输出它们的和.差.积.整数商和余数.*/ #include<stdio.h> int main() { int num1, num2; ...

  9. mysql中explain查看sql语句索引使用情况

    explain + sql: mysql> explain select * from user; +----+-------------+-------+------+------------ ...

  10. 洛谷P1064 金明的预算方案(01背包)

    题目描述 金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间金明自己专用的很宽敞的房间.更让他高兴的是,妈妈昨天对他说:“你的房间需要购买哪些物品,怎么布置,你说了算,只要不超过NNN元钱就行” ...