分治、二分
分治、二分
分治:
-
就是分解成若干小规模问题解决
-
分治的步骤:
-

-
示例:汉诺塔问题、归并排序
-
归并排序求逆序对
-
#include<iostream> using namespace std; int n; int a[50010]; int b[50010]; long long ans = 0; void merge_sort(int left,int right ) { if (left==right) { return; } else { int mid = (left + right) / 2; int i = left, j = mid + 1, k = left; merge_sort(left, mid); merge_sort(mid + 1, right); //左右都有数 while (i <= mid && j <= right) { if (a[i] < a[j]) { b[k++] = a[i++];//不是逆序对,b数组存小的数 } else { b[k++] = a[j++];//是逆序对 ans += mid - i + 1; /* 记录逆序对数,根据下标来判断有几个逆序数, 比如3142,有两个逆序对,先判断3,ans=1-0+1=2,即3-1,3-2 又比如2314,有2个逆序对,先判断2,ans=1-0+1=2,即2-1,3-1(不管第二个数比第一个大还是比第一个小,总是mid-i+1) */ } } //左边有数右边没了 while (i <= mid) { b[k++] = a[i++]; } //右边有数左边没了 while (j <= right) { b[k++] = a[j++]; } for (int i = 1; i <= right; i++) { a[i] = b[i]; } } } int main() { cin >> n; for (int i = 1; i <= n; i++) { cin >> a[i]; } merge_sort(1, n); printf("%lld", ans); return 0; }
二分:
-
算法:当数据量很大适宜采用该方法。采用二分法查找时,数据需是排好序的 。
基本思想:假设数据是按升序排序的,对于给定值key,从序列的中间位置k开始比较,
如果当前位置arr[k]值等于key,则查找成功;
若key小于当前位置值arr[k],则在数列的前半段中查找,arr[low,mid-1];
若key大于当前位置值arr[k],则在数列的后半段中继续查找arr[mid+1,high],
直到找到为止,时间复杂度:O(log(n))。

浙公网安备 33010602011771号