hash一下 + 归并排序计算逆序对数
来源:互联网 发布:mac gdb 动态调试程序 编辑:程序博客网 时间:2024/05/16 13:39
OJ题目:click here~~
题目分析:给一个序列,选择两个数,交换这两个数的位置,使得交换后,序列的逆序数最少。给出交换后的逆序数。
先将序列中的数hash一下,是为了下面方便计算数的次数。
归并排序,求逆序数。
枚举所有可选的两个数a , b,计算这两个数之间,比a大的数,比a小的数,比b大的数,比b小的数。交换a , b 之后 ,逆序数 = 原来的逆序数 + 比a大的数 + 比b小的数 - 比a小的数 - 比b大的数 + a,b逆序数的变化。
AC_CODE
const int Max_N = 1002;int x[Max_N] , h[Max_N] , sum ;int dpless[Max_N][Max_N] ;//dp[i][j];到i处为止,比j小的数的个数int dpbig[Max_N][Max_N] ;//dpbig[i][j]:到i处为止,比j大的数的个数void Merg(int L , int R){ if(L == R) return ; int M = (L + R)>>1; Merg(L , M); Merg(M + 1 , R); for(int i = M + 1;i <= R;i++){ sum += (x + 1 + M) - upper_bound(x + L , x + 1 + M , x[i]); } sort(x + L , x + R + 1);}int main(){ int i , j , k , n; while(scanf("%d",&n) != EOF){ for(i = 1;i <= n;i++){ scanf("%d",&x[i]); h[i] = x[i]; } //先hash一下 sort(x + 1 , x + 1 + n);//需要先排序 int len = unique(x + 1, x + 1 + n) - (x + 1);//不同的元素的个数 for(i = 1;i <= n;i++) h[i] = lower_bound(x + 1 , x + 1 + len , h[i]) - x; for(i = 1;i <= n;i++) x[i] = h[i]; sum = 0 ; Merg(1 , n) ;//求原来序列的逆序数 if(!sum){ puts("0") ; continue; } memset(dpless , 0 , sizeof(dpless)); memset(dpbig , 0 , sizeof(dpbig)); for(i = 1;i <= n;i++) x[i] = h[i]; for(i = 1;i <= n;i++){ for(j = 1;j <= len;j++) dpless[i][j] = dpless[i - 1][j]; for(j = x[i] + 1;j <= len;j++) dpless[i][j]++; for(j = 1;j <= len;j++) dpbig[i][j] = dpbig[i - 1][j]; for(j = 1;j < x[i];j++) dpbig[i][j]++; } int ans = sum; int a , b , aless , bless , abig , bbig ; for(i = 1;i <= n;i++){ for(j = i + 1;j <= n;j++){ a = x[i]; b = x[j]; bless = dpless[j - 1][b] - dpless[i][b]; bbig = dpbig[j - 1][b] - dpbig[i][b]; abig = dpbig[j - 1][a] - dpbig[i][a]; aless = dpless[j - 1][a] - dpless[i][a]; int k = 0 ; if(a < b) k = 1; if(b < a) k = -1; ans = min(ans , sum + bless + abig - aless - bbig + k); } } cout << ans << endl; }}
0 0
- hash一下 + 归并排序计算逆序对数
- 归并排序同时计算逆序对数
- 归并排序-逆序对数
- 归并排序求逆序对数)
- 归并排序&求逆序对数
- 归并排序求逆序对数
- 归并排序求逆序对数
- 归并排序及逆序对数
- 归并排序之逆序对数
- 归并排序求逆序对数
- 逆序对数(归并排序)
- 【java】归并排序 逆序对数
- 边归并排序,边统计逆序对数
- 归并排序 and 逆序对数(分治)
- 求逆序对数(利用归并排序)
- POJ 2299 归并排序 求逆序对数
- 归并排序算法求逆序对数
- 归并排序及利用归并排序求逆序对数
- final关键字
- 根据给定一串数值找出其规律然后求前20项之和的代码实现(1,、4、5、9、14、23、37...)
- intent服务
- 安卓学习之路_20140505_EditText、SQLite语法
- 在10g oracle里面如何修改为手工归档
- hash一下 + 归并排序计算逆序对数
- Tyvj p1371 蛇灵迷宫 (博弈 输出路径)
- 优先队列+模拟-Fox and Number Game
- hdu 1023 Train Problem II
- 浏览器的不兼容
- Visual C++中DDB与DIB位图编程全攻略
- OpenCV学习笔记(4)之鼠标事件
- 缓解疲劳的方法
- 利用Node.js与PDFKIT 生成PDF文件