Description
小 A 收到了一封来自外星球的秘密邮件。邮件由 n(n≤1000000) 个大写英文字母组成,不巧的是小A 收到邮件以后一不小心打乱了原来的字母顺序。但是聪明的小 A 记住了原邮件的完整内容,现在她每次可以选择打乱后的邮件中相邻的两个字母进行交换,问最少交换多少次能够将打乱的邮件恢复成原邮件。
题解
考虑将问题转化为序列上面的问题,
我们将目标串视作是一个有序的序列,而且就认为是1到n。
考虑如何将原串对应,
显然是相同字母的位置相对于,
如果相同字母很多的话,显然是第一个对应第一个,第二个对于第二个,如此类推。
考虑如果第一个对应第二个,第二个对于第一个,这样他们在交换的时候就会有重复的,显然是不优的。
现在考虑如何求最小交换次数,
可以知道,每次交换可以减少一个逆序对的个数,
于是答案就是逆序对个数。
code
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
char ch;
void read(int&n)
{
for(ch=getchar();ch<'0' || ch>'9';ch=getchar());
for(n=0;'0'<=ch && ch<='9';ch=getchar())n=(n<<1)+(n<<3)+