bzoj2789.Letters(贪心 && 逆序数)
2015-11-03 10:46
211 查看
有两个长度为 n 的由大写英文字母组成的字符串A, B,问最少需要多少次交换( 相邻两个交换 )才能使 A 变为 B ( 保证可以实现 )
首先的一个想法就是:要想总交换次数最小,A , B 中的相同字母要相距的距离最小( 贪心 )。然后就可以根据 A 中每个字母的位置, 把 B 对应成一个序列,求这个序列的逆序数。
首先的一个想法就是:要想总交换次数最小,A , B 中的相同字母要相距的距离最小( 贪心 )。然后就可以根据 A 中每个字母的位置, 把 B 对应成一个序列,求这个序列的逆序数。
/* Author: JDD PROG: bzoj2789.letters DATE: 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; }
相关文章推荐
- windows8下iis7配置网站遇到的问题
- POI读取Excel2013
- Android性能优化典范
- mysql 远程账户
- LeetCode--Add Digits
- DedeCMS织梦系统head.htm里无法调用栏目描述
- .net 自定义配置文件
- ORACLE隐含列
- 欢迎使用CSDN-markdown编辑器
- 笔记
- 最大似然度或者最大似然估計
- C++类的构造函数及操作符()重载
- 拖动条SeekBar
- TCP长链接调试利器nc
- Leetcode137: Remove Duplicates from Sorted List II
- 从github 下载项目 , 并且提交
- UIAlertController 弹框提醒
- UIMenuController的使用,对UILabel拷贝以及定制菜单
- MyBatis:The expression 'list' evaluated to a null value
- Spring-XML配置AOP-案例