我是靠谱客的博主 踏实自行车,最近开发中收集的这篇文章主要介绍HDU1394:Minimum Inversion Number,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

Problem Description
The inversion number of a given number sequence a1, a2, ..., an is the number of pairs (ai, aj) that satisfy i < j and ai > aj.

For a given sequence of numbers a1, a2, ..., an, if we move the first m >= 0 numbers to the end of the seqence, we will obtain another sequence. There are totally n such sequences as the following:

a1, a2, ..., an-1, an (where m = 0 - the initial seqence)
a2, a3, ..., an, a1 (where m = 1)
a3, a4, ..., an, a1, a2 (where m = 2)
...
an, a1, a2, ..., an-1 (where m = n-1)

You are asked to write a program to find the minimum inversion number out of the above sequences.
 

Input
The input consists of a number of test cases. Each case consists of two lines: the first line contains a positive integer n (n <= 5000); the next line contains a permutation of the n integers from 0 to n-1.
 

Output
For each case, output the minimum inversion number on a single line.
 

Sample Input
  
  
10 1 3 6 9 0 8 5 7 4 2
 

Sample Output
  
  
16
 


 

 

弄了半天才弄懂题目的意思,就是求最小的逆序数,在此贴下逆序数的概念

在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个 逆序。一个排列中逆序的总数就称为这个排列的 逆序数。逆序数为偶数的排列称为 偶排列;逆序数为奇数的排列称为 奇排列。如2431中,21,43,41,31是逆序,逆序数是4,为偶排列。
也是就说,对于n个不同的元素,先规定各元素之间有一个标准次序(例如n个 不同的自然数,可规定从小到大为标准次序),于是在这n个元素的任一排列中,当某两个元素的先后次序与标准次序不同时,就说有1个逆序。一个排列中所有逆序总数叫做这个排列的逆序数。

 

题目的意思就好比给出一个序列

如:0 3 4 1 2

设逆序数初始n = 0;

由于0后面没有比它小的,n = 0

3后面有1,2 n = 2

4后面有1,2,n = 2+2 = 4;

所以该序列逆序数为 4

其根据题意移动产生的序列有

3 4 1 2 0   逆序数:8

4 1 2 0 3  逆序数:6

1 2 0 3 4  逆序数:2

2 0 3 4 1  逆序数:4

所以最小逆序数为2

 

 

#include <iostream>
#include <cmath>
using namespace std;

struct Tree
{
    int l,r,mid;
    int sum;
}T[15555];

int min(int a,int b)
{
    return a>b?b:a;
}

void build(int l,int r,int k)
{
    T[k].l = l;
    T[k].r = r;
    T[k].mid = (l+r) >> 1;
    T[k].sum = 0;
    if (l == r)
    return ;
    build(l,T[k].mid,k << 1);
    build(T[k].mid+1,r,k<<1|1);
}

void insert(int aim,int l,int r,int k)
{
    if(T[k].l == aim && T[k].r == aim)
    {
        T[k].sum++;
        return;
    }
    if(aim <= T[k].mid)
    insert(aim,l,T[k].mid,k<<1);
    else
    insert(aim,T[k].mid+1,r,k<<1|1);
    T[k].sum = T[k<<1].sum + T[k<<1|1].sum;
}

int ans;
void search(int l,int r,int k)
{
    if(T[k].l == l && T[k].r == r)
    {
        ans+=T[k].sum;
        return ;
    }
    if(r <= T[k].mid)
    search(l,r,k<<1);
    else if(l > T[k].mid)
    search(l,r,k<<1|1);
    else
    {
        search(l,T[k].mid,k<<1);
        search(T[k].mid+1,r,k<<1|1);
    }
}

int main()
{
    int n,i,num[5005],sum,text;
    while(cin >> n)
    {
        build(1,n,1);
        sum = 0;
        for(i = 0;i<n;i++)
        {
            cin >> num[i];
            num[i]++;
            ans = 0;
            if(num[i]!=n)
            search(num[i]+1,n,1);
            sum += ans;
            insert(num[i],1,num[i],1);
        }
        text = sum;
        for(i = n-1;i>=0;i--)
        {
            sum = sum - (n-num[i])+(num[i]-1);
            text = min(text,sum);
        }
        cout << text << endl;
    }

    return 0;
}


 

 

 

最后

以上就是踏实自行车为你收集整理的HDU1394:Minimum Inversion Number的全部内容,希望文章能够帮你解决HDU1394:Minimum Inversion Number所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(59)

评论列表共有 0 条评论

立即
投稿
返回
顶部