1、小和问题:类似月逆序对问题,是求给定序列中每个数前面比其小的数,然后累加,求出总和sum
2、代码
(1)暴力求解,时间复杂度O(n^2)
//小和问题O(n^2) #include<bits/stdc++.h> using namespace std; int main() { int n, i , j; int a[100]; while(~scanf("%d",&n)) { for(i = 0; i < n; i++) scanf("%d",&a[i]); int res = 0; for(i = 1; i < n; i++) { for(int j = 0; j < i; j++) if(a[j] < a[i]) res += a[j]; } printf("%d\n",res); } } /* 5 3 5 1 4 6 */
(2)归并排序求解,时间复杂度O(nlogn)
//Mergesort 应用 小和问题O(nlogn) #include<bits/stdc++.h> using namespace std; const int maxn = 100; int temp[maxn]; int Merge(int a[], int l, int mid, int r) { int i = l,j = mid + 1,k = 0; int res = 0; while(i <= mid && j <= r) { if(a[i] < a[j]) { res += (r - j + 1) * a[i]; temp[k++] = a[i++]; } else { temp[k++] = a[j++]; } } while(i <= mid) { temp[k++] = a[i++]; } while(j <= r) { temp[k++] = a[j++]; } for(int i = l, k = 0; i <= r; i++,k++) a[i] = temp[k]; return res; } int MergeSort(int a[], int l, int r) { if(l == r) return 0; int mid = l + ((r-l)>>1); return MergeSort(a,l,mid) + MergeSort(a,mid+1,r) + Merge(a,l,mid,r); } int main() { int n; int a[maxn]; while(~scanf("%d",&n)) { for(int i = 0; i < n; i++) scanf("%d",&a[i]); int smallsum = MergeSort(a,0,n-1); printf("%d\n",smallsum); } return 0; } /* 5 3 5 1 4 6 */