CodeForces 1238E Keyboard Purchase【状压DP】

K e y b o a r d   P u r c h a s e Keyboard\ Purchase Keyboard Purchase

Description:
You have a password which you often type — a string s of length n. Every character of this string is one of the first m lowercase Latin letters.

Since you spend a lot of time typing it, you want to buy a new keyboard.

A keyboard is a permutation of the first m Latin letters. For example, if m=3, then there are six possible keyboards: abc, acb, bac, bca, cab and cba.

Since you type your password with one finger, you need to spend time moving your finger from one password character to the next. The time to move from character si to character si+1 is equal to the distance between these characters on keyboard. The total time you have to spend typing the password with a keyboard is called the slowness of this keyboard.

More formaly, the slowness of keyboard is equal to ∑i=2n|possi−1−possi|, where posx is position of letter x in keyboard.

For example, if s is aacabc and the keyboard is bac, then the total time of typing this password is |posa−posa|+|posa−posc|+|posc−posa|+|posa−posb|+|posb−posc| = |2−2|+|2−3|+|3−2|+|2−1|+|1−3| = 0+1+1+1+2=5.

Before buying a new keyboard you want to know the minimum possible slowness that the keyboard can have.

Input:
The first line contains two integers n and m (1≤n≤105,1≤m≤20).

The second line contains the string s consisting of n characters. Each character is one of the first m Latin letters (lowercase).

Output:
Print one integer – the minimum slowness a keyboard can have.

Sample Input:

  • 6 3
    aacabc

Sample Output:

  • 5

Sample Input:

  • 6 4
    aaaaaa

Sample Output:

  • 0

Sample Input:

  • 15 4
    abacabadabacaba

Sample Output:

  • 16
TJ:

神奇的状压DP,枚举子集
首先处理出字符串中所有相邻字符出现的次数,把字母从0~m-1编号,每个字母相当于一个顶点,字符串中的相邻字符相当于连了一条边,连接相邻两个顶点,现在要求给各个顶点赋值(各不相同),两点之间的边权为两点权值之差的绝对值,现在要求找出一种赋值方法,使得所有边权的总和最小。
如何解决这个问题?
我们考虑现在有一个数列,然后从左往右加入各个点,而点赋值为其在数列中的下标。
假设当前数列长度为k,则在此之后加入的点的下标必然比数列中已经存在的点大(废话),由于要求边权的和,放在这个数列中就相当于求两点在数列中的相对距离(r-l+1) x 边的数量,而这个距离如何算呢,考虑现在已经加入的数列的顶点集合为msk(可以用一个二进制数来表示),但是现在不知道msk所表示的集合的排列顺序(即在数列中的顺序),但是没关系,我们把当前数列看成一个点(缩点,设为S),然后由于后面的点和S点的距离至少为1,所以我们把最小的可能距离记下来,即S点和之后所有点的连边数量x1
我们发现对于这个方法,对于当前枚举的子集,后面再加入点所产生的贡献和当前集合的顺序没有关系了,而当前集合对之后答案的贡献只和当前集合中数的插入的顺序有关,所以只要找出当前集合以什么顺序排列能得到对之后的贡献最少即可,这个只要枚举最后一个插入的数是什么就行了,记录最优值,子集DP。

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1e5+7;
const int MAXM = 20;
const int INF = 0x3f3f3f3f;
int f[1<<MAXM],n,m,cnt[MAXM][MAXM];
char s[MAXN];
int main(){
	scanf("%d %d %s",&n,&m,s);
	for(int i = 1; i < n; i++) {
		cnt[s[i]-'a'][s[i-1]-'a']++;
		cnt[s[i-1]-'a'][s[i]-'a']++;
	}
	memset(f,INF,sizeof(f));
	f[0] = 0;
	for(int msk = 1; msk < (1<<m); msk++) {//枚举子集
		int c = 0;			//当前集合对之后所有数的最小贡献
		for(int i = 0; i < m; i++){
			for(int j = i + 1; j < m; j++){
				if((msk>>i&1) ^ (msk>>j&1)) c += cnt[i][j];
			}
		}
		for(int i = 0; i < m; i++){		//枚举最后加入的数
			if(1<<i&msk) f[msk] = min(f[msk], f[msk^(1<<i)] + c);
		}
	}
	printf("%d\n",f[(1<<m)-1]);
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
4S店客户管理小程序-毕业设计,基于微信小程序+SSM+MySql开发,源码+数据库+论文答辩+毕业论文+视频演示 社会的发展和科学技术的进步,互联网技术越来越受欢迎。手机也逐渐受到广大人民群众的喜爱,也逐渐进入了每个用户的使用。手机具有便利性,速度快,效率高,成本低等优点。 因此,构建符合自己要求的操作系统是非常有意义的。 本文从管理员、用户的功能要求出发,4S店客户管理系统中的功能模块主要是实现管理员服务端;首页、个人中心、用户管理、门店管理、车展管理、汽车品牌管理、新闻头条管理、预约试驾管理、我的收藏管理、系统管理,用户客户端:首页、车展、新闻头条、我的。门店客户端:首页、车展、新闻头条、我的经过认真细致的研究,精心准备和规划,最后测试成功,系统可以正常使用。分析功能调整与4S店客户管理系统实现的实际需求相结合,讨论了微信开发者技术与后台结合java语言和MySQL数据库开发4S店客户管理系统的使用。 关键字:4S店客户管理系统小程序 微信开发者 Java技术 MySQL数据库 软件的功能: 1、开发实现4S店客户管理系统的整个系统程序; 2、管理员服务端;首页、个人中心、用户管理、门店管理、车展管理、汽车品牌管理、新闻头条管理、预约试驾管理、我的收藏管理、系统管理等。 3、用户客户端:首页、车展、新闻头条、我的 4、门店客户端:首页、车展、新闻头条、我的等相应操作; 5、基础数据管理:实现系统基本信息的添加、修改及删除等操作,并且根据需求进行交流信息的查看及回复相应操作。
现代经济快节奏发展以及不断完善升级的信息化技术,让传统数据信息的管理升级为软件存储,归纳,集中处理数据信息的管理方式。本微信小程序医院挂号预约系统就是在这样的大环境下诞生,其可以帮助管理者在短时间内处理完毕庞大的数据信息,使用这种软件工具可以帮助管理人员提高事务处理效率,达到事半功倍的效果。此微信小程序医院挂号预约系统利用当下成熟完善的SSM框架,使用跨平台的可开发大型商业网站的Java语言,以及最受欢迎的RDBMS应用软件之一的MySQL数据库进行程序开发。微信小程序医院挂号预约系统有管理员,用户两个角色。管理员功能有个人中心,用户管理,医生信息管理,医院信息管理,科室信息管理,预约信息管理,预约取消管理,留言板,系统管理。微信小程序用户可以注册登录,查看医院信息,查看医生信息,查看公告资讯,在科室信息里面进行预约,也可以取消预约。微信小程序医院挂号预约系统的开发根据操作人员需要设计的界面简洁美观,在功能模块布局上跟同类型网站保持一致,程序在实现基本要求功能时,也为数据信息面临的安全问题提供了一些实用的解决方案。可以说该程序在帮助管理者高效率地处理工作事务的同时,也实现了数据信息的整体化,规范化与自动化。
引用\[1\]中提到了一种树形动态规划的方法来解决CodeForces - 982C问题。在这个问题中,subtree指的是子连通块,而不是子树。为了使cnt_white - cnt_black尽可能大,可以使用两次树形动态规划来求解。第一次是自底向上的过程,维护一个dp数组,表示以每个节点为根的子树中的最大连通块。第二次是自顶向下的过程,处理自底向上过程中无法包含的树链所代表的子树。在第二次遍历中,需要维护一个sum变量,用于存储树链所代表的子树的贡献。根据ans\[u\]的正负,决定是否能对相邻的子节点做出贡献。如果ans\[u\]为正,则减去dp\[v\]就是树链所代表的子树的权值。最终,ans\[u\]代表包含节点u在内的子连通块的最大权值。\[1\] 问题: CodeForces - 982C 树形DP是什么问题?如何解决? 回答: CodeForces - 982C是一个树形动态规划问题。在这个问题中,需要求解子连通块的最大权值和,使得cnt_white - cnt_black尽可能大。解决这个问题的方法是使用两次树形动态规划。第一次是自底向上的过程,维护一个dp数组,表示以每个节点为根的子树中的最大连通块。第二次是自顶向下的过程,处理自底向上过程中无法包含的树链所代表的子树。在第二次遍历中,需要维护一个sum变量,用于存储树链所代表的子树的贡献。根据ans\[u\]的正负,决定是否能对相邻的子节点做出贡献。最终,ans\[u\]代表包含节点u在内的子连通块的最大权值。\[1\] #### 引用[.reference_title] - *1* *2* [CodeForces - 1324F Maximum White Subtree(树形dp)](https://blog.csdn.net/qq_45458915/article/details/104831678)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值