排序-構造題

傳送門:排序

題意:給出一段包含’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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章