排序-构造题

传送门:排序

题意:给出一段包含’A’,‘T’,‘G’,‘C’的序列,每个字母可以和左右字母交换位置,每次交换造成一个消耗,构造出’A’,‘T’,‘G’,'C’分别连续的序列,求出最小的消耗。
解析:首先枚举24种可能,即’A’,‘T’,‘G’,'C’的排列顺序,统计每种可能的消耗。对于求每种情况的消耗,需要一个类似于求逆序数的思想。假设求ATGC的情况,那么遍历原序列,没到一个字母边查询在它之前且序列优先级(即A的优先级最高,T,G,C依次降低)没它高的字母有多少个。这些字母一定要被移动到它后边的,那么统计数加上这些字母的个数,那么这些字母就算是到它后边了。查询可以用前缀数组

代码:

#include<bits/stdc++.h>
using namespace std;
char s[200010];
map<char,int> mmp;
int flag[2000010];
int main(){
	scanf("%s",s+1);
	int n=strlen(s+1);
	int a[]={0,1,2,3,4};
	long long Min=LONG_LONG_MAX;
	while(next_permutation(a+1,a+4+1)){
		memset(flag,0,sizeof flag);
		mmp['A']=a[1],mmp['T']=a[2],mmp['G']=a[3],mmp['C']=a[4];
		long long ans=0;
		for(int i=1;i<=n;++i){
			for(int j=mmp[s[i]]+1;j<=4;++j){
				ans+=flag[j];
			}
			flag[mmp[s[i]]]++;
		}
		Min=min(ans,Min);
	}
	cout<<Min<<endl;
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章