bzoj2789.Letters(贪心 && 逆序数)

来源:互联网 发布:新顶级域名有哪些 编辑:程序博客网 时间:2024/06/05 15:14

       有两个长度为 n 的由大写英文字母组成的字符串A, B,问最少需要多少次交换( 相邻两个交换 )才能使 A 变为 B ( 保证可以实现 )

       首先的一个想法就是:要想总交换次数最小,A , B 中的相同字母要相距的距离最小( 贪心 )。然后就可以根据 A 中每个字母的位置, 把 B 对应成一个序列,求这个序列的逆序数。

/*Author: JDDPROG: bzoj2789.lettersDATE: 2015.11.03*/#include <cstdio>#include <queue>using namespace std;const int MAX_N = 1000005;#define low(x) (x & (-x))int n, c[MAX_N];queue<int> q[30];void insert(int x, int p){for(int i = x; i <= n; i += low(i))c[i] += p;}int query(int x){int ret = 0;for(int i = x; i > 0; i -= low(i))ret += c[i];return ret;}void init(){scanf("%d", &n);char s[MAX_N]; scanf("%s", s + 1);for(int i = 1; i <= n; i ++)q[s[i] - 'A' + 1].push(i); }void doit(){char s[MAX_N]; scanf("%s", s + 1);long long ans = 0;for(int i = 1; i <= n; i ++){int p = q[s[i] - 'A' + 1].front(); q[s[i] - 'A' + 1].pop();insert(p, 1);ans += i - query(p);}printf("%lld\n", ans);}int main(){freopen("1.in", "r", stdin);init(); doit();return 0;}

 

0 0
原创粉丝点击