题目链接
题目描述
给出用只包含'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;
}