牛客练习赛54 C.排序(字符串、映射、思维)

题目链接

题目描述

给出用只包含'A','G','C','T'的字符串s,s[i]和s[j]交换的代价为2*(j-i)-1,求将序列串中同种字符划分到一起的最小花费。

题目思路

因为只有4种字符,所以可以暴力枚举出 序列串中同种字符划分到一起 不同种类字符的相对位置,对每一种情况,计算代价和,详见代码。

#include<bits/stdc++.h>
#define LL long long
#define INF 0x3f3f3f3f3f3f3f3f
using namespace std;
const int maxn=200005;
const int mod=998244353;
string z="AGCT";	
string s;
int a[4],hx[maxn],num[10];
LL ans,mini;
void init()//将原字符串与数字映射 
{
	for(int i=0;i<s.length();i++)
	{
		if(s[i]=='A')
			hx[i]=a[0];//i位置的字母最后应该停留的位置 
		else if(s[i]=='G')
			hx[i]=a[1];
		else if(s[i]=='C')
			hx[i]=a[2];
		else
			hx[i]=a[3];
	}
}
void solve()
{
	init();
	ans=0;
	memset(num,0,sizeof(num));
	for(int i=0;i<s.length();i++)
	{
		int ix=hx[i];
		for(int j=ix+1;j<4;j++)//比ix大的,之前出现过的数 
		{
			ans+=num[j];//累积ix需要移动的次数
		}
		num[ix]++;//更新贡献值,加一 
	}
	mini=min(ans,mini);
}
int main()
{

	cin>>s;
	for(int i=0;i<4;i++) a[i]=i;
	mini=INF;
	do
	{
		solve();
	}while(next_permutation(a,a+4));
	cout << mini << endl;
	return 0;
} 
posted @ 2019-11-19 15:19  loveyixuan  阅读(152)  评论(0)    收藏  举报