ZOJ 1484 题解

    题目链接:http://acm.zju.edu.cn/show_problem.php?pid=1484

    排到这一题了,呵呵。

    题目的要求很简单,给出一个长为n的序列是,这个序列中的数是各不相同的,而且范围是0到n-1,要求得到的是一个最短的逆序的长度,这些子序列是转动原 来的序列得到的。

    当然,这个题目肯定不能死做,每个都试一下,这样的时间复杂度是O(N*N*N),这样做肯定超时,其实我们可以看到的是,下一个序列的逆序长度与当前序 列的逆序长度是有关系的,因为这个序列是很特殊的序列,各个数不同且范围在1到n-1,于是可以得到cur = cur - a[i] + n - a[i] - 1,这样就不会超时了。

    速度虽然不是很快,但是起码能过。

    代码如下:in C++

代码
 1     题目链接:http://acm.zju.edu.cn/show_problem.php?pid=1484
 2 
 3     排到这一题了,呵呵。
 4 
 5     题目的要求很简单,给出一个长为n的序列是,这个序列中的数是各不相同的,而且范围是0到n-1,要求得到的是一个最短的逆序的长度,这些子序列是转动原来的序列得到的。
 6 
 7     当然,这个题目肯定不能死做,每个都试一下,这样的时间复杂度是O(N*N*N),这样做肯定超时,其实我们可以看到的是,下一个序列的逆序长度与当前序列的逆序长度是有关系的,因为这个序列是很特殊的序列,各个数不同且范围在1到n-1,于是可以得到cur = cur - a[i] + n - a[i] - 1,这样就不会超时了。
 8 
 9     速度虽然不是很快,但是起码能过。
10 
11     代码如下:in C++
12 
13 #include<iostream>
14 #include<cstdio>
15 using namespace std;
16 
17 int main()
18 {
19 int a[5001] ;
20 int n ;
21 int min_inv_num ;
22 
23 while(scanf("%d",&n) != EOF)
24 {
25    for(int i = 0 ; i < n ; i ++)
26     scanf("%d"&a[i]) ;
27    min_inv_num = 0 ;
28    for(int i = 0 ; i < n ; i ++)
29     for(int j = i + 1 ; j < n ; j ++)
30     {
31      if(a[i] > a[j])
32       min_inv_num ++ ;
33     }
34    int cur = min_inv_num ;
35    for(int i = 0 ; i < n - 1 ; i ++)
36    {
37     cur = cur - a[i] + n - a[i] - 1 ;
38     if(cur < min_inv_num)
39    }
40    printf("%d\n",min_inv_num) ;
41 }
42 
43 return 0;
44 }


posted on 2010-02-05 01:53  vivy  阅读(373)  评论(0编辑  收藏  举报