傳送門:排序
題意:給出一段包含’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;
}