您的位置:首页 > 其它

ACM: 序列中找最小逆序对 杂题 TOJ…

2016-05-19 23:19 375 查看


            
Minimum Inversion Number

描述

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.

输入

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.

输出

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

样例输入
10
1 3 6 9 0 8 5
7 4 2
样例输出
16
 
题意:
在规定的变化序列中找出最少逆序对的个数.
 
解题思路:
               
1. 先计算出初始序列的逆序对的个数.
               
2. 再计算把当前序列最后一个数放到最前面的时候逆序对变化.
               
问题分析:  假设 sum 表示当前序列的逆序对数.
num表示当前序列最后一个数.
                               
要计算变化的情况首先, 假设最坏的情况. 即: sum -= (n-1);
                                再
sum += (num的逆序对)*2
                
3. 不断更新最小值.
代码:
#include
<cstdio>

#include <iostream>

#include <cstring>

using namespace std;

#define MAX 5005
int n;

int sum;

int minsize;

int a[MAX];
int
main()

{

 freopen("input.txt","r",stdin);

 int i, j;

 while(scanf("%d",&n) !=
EOF)

 {

  sum = 0;

  for(i = 0; i <
n; ++i)

   scanf("%d",&a[i]);

  

  for(i = 0; i <
n; ++i)

  {

   for(j = i+1;
j < n; ++j)

   {

    if(a[i]
> a[j])

     sum++;

   }

  }
  minsize = sum;

  for(i = n-1; i >
0; --i)

  {

   sum = (sum -
(n-1));

   sum = (sum +
(a[i]*2));

   if(minsize
> sum)

    minsize
= sum;

  }

  printf("%d\n",minsize);

 }

 return 0;

}

 
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: