归并排序应用-------小和问题

Posted hhkobeww

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了归并排序应用-------小和问题相关的知识,希望对你有一定的参考价值。

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
*/

 

以上是关于归并排序应用-------小和问题的主要内容,如果未能解决你的问题,请参考以下文章

归并排序:小和问题

归并排序之求小和

归并排序解决小和问题和逆序对问题

小和问题和逆序对问题

求小和问题

小和问题与荷兰国旗问题