zoukankan      html  css  js  c++  java
  • 洛谷P1774 最接近神的人_NOI导刊2010提高(02)(求逆序对)

    To 洛谷.1774 最接近神的人

    题目描述

    破解了符文之语,小FF开启了通往地下的道路。当他走到最底层时,发现正前方有一扇巨石门,门上雕刻着一幅古代人进行某种活动的图案。而石门上方用古代文写着“神的殿堂”。小FF猜想里面应该就有王室的遗产了。但现在的问题是如何打开这扇门……

    仔细研究后,他发现门上的图案大概是说:古代人认为只有智者才是最容易接近神明的。而最聪明的人往往通过一种仪式选拔出来。仪式大概是指,即将隐退的智者为他的候选人写下一串无序的数字,并让他们进行一种操作,即交换序列中相邻的两个元素。而用最少的交换次数使原序列变成不下降序列的人即是下一任智者。

    小FF发现门上同样有着n个数字。于是他认为打开这扇门的秘诀就是找到让这个序列变成不下降序列所需要的最小次数。但小FF不会……只好又找到了你,并答应事成之后与你三七分……

    输入输出格式

    输入格式:

    第一行为一个整数n,表示序列长度

    第二行为n个整数,表示序列中每个元素。

    输出格式:

    一个整数ans,即最少操作次数。

    输入输出样例

    输入样例#1:
    4
    2 8 0 3
    
    输出样例#1:
    3
       样例说明:开始序列为2 8 0 3,目标序列为0 2 3 8,可进行三次操作的目标序列:
        1.Swap (8,0):2  0  8  3
        2.Swap (2,0):0  2  8  3
        3.Swap (8,3):0  2  3  8
    

    说明

    对于30%的数据1≤n≤10^4。

    对于100%的数据1≤n≤5*10^5;

    -maxlongint≤A[i]≤maxlongint。

    思路:

      求逆序对。最优方案每移动一次必定消且仅消去一个逆序对。

    代码:

     1 #include<cstdio>
     2 #define gc getchar()
     3 using namespace std;
     4 const int maxn=500010;
     5 
     6 int n,num[maxn],tmp[maxn];
     7 long long ans;
     8 
     9 void read(int &x)
    10 {
    11     x=0;char c=gc;bool flag=0;
    12     while(c<'0'||c>'9')
    13     {
    14         if(c=='-') flag=1;
    15         c=gc;
    16     }
    17     while(c>='0'&&c<='9') x=x*10+c-'0',c=gc;
    18     if(flag) c=-c;
    19 }
    20 
    21 void mergearray(int l,int r)
    22 {
    23     int i=l,m=(l+r)>>1;
    24     int m2=m+1,cnt=0;
    25     while(i<=m&&m2<=r)
    26     {
    27         if(num[i]<=num[m2])
    28           tmp[cnt++]=num[i++];
    29         else
    30           ans+=m-i+1,tmp[cnt++]=num[m2++];
    31     }
    32     while(i<=m)
    33       tmp[cnt++]=num[i++];
    34     while(m2<=r)
    35       tmp[cnt++]=num[m2++];
    36     for(int q=0;q<cnt;q++)
    37       num[l+q]=tmp[q];
    38 }
    39 void mergesort(int l,int r)
    40 {
    41     if(l<r)
    42     {
    43         int m=(l+r)>>1;
    44         mergesort(l,m);
    45         mergesort(m+1,r);
    46         mergearray(l,r);
    47     }
    48 }
    49 int main()
    50 {
    51     //read(n);
    52     scanf("%d",&n);
    53     for(int i=1;i<=n;i++)
    54       scanf("%d",&num[i]);
    55       //read(num[i]);
    56     mergesort(1,n);
    57     printf("%lld",ans);
    58     return 0;
    59 }
    ------------------------------------------------------------------------------------------------------------------------
    无心插柳柳成荫才是美丽
    有哪种美好会来自于刻意
    这一生波澜壮阔或是不惊都没问题
    只愿你能够拥抱那种美丽
    ------------------------------------------------------------------------------------------------------------------------
  • 相关阅读:
    Python学习小目录汇总
    进制转换的知识
    计算机组成原理目录
    python基础知识-8-三元和一行代码(推导式)
    python基础知识-7-内存、深浅、文件操作
    IT工具使用
    Python基础知识-06-集合内存布尔False
    Python基础知识-05-数据类型总结字典
    elk收集tomcat日志
    pycharm重命名文件
  • 原文地址:https://www.cnblogs.com/SovietPower/p/6893625.html
Copyright © 2011-2022 走看看