要想对任意(ai,bi)和(a和b­j),当ai<aj时,都有bi<=bj;当ai>=aj时,bi>=bj,当对a进行升序排序后(b同时发生改变,从而不改变值,最后有a1<=a2<=…<=an),必须满足b1<=b2<=…<=b­n

否则,必存在(ai,bi)和(a和b­j),有ai<aj且bi>bj,交换ai和aj后,(aj*bi+ ai*bj)-( ai*bi+ aj*bj)=(aj-ai)*( bi-bj)>0,数值更小,即不是所满足的序列。

唯有满足条件“对任意(ai,bi)和(a和b­j),当ai<aj时,都有bi<=bj;当ai>=aj时,bi>=bj”的序列才是值最小的序列。

最后目的是:对任意(ai,bi)和(a和b­j),当ai<aj时,都有bi<=bj;当ai>=aj时,bi>=bj,其中题目限制“同一列火柴的高度互不相同”,所以对a,b序列进行从小到大排序,数的编号具有唯一性,即最后a,b两个序列中,ai在a序列的编号等于bi在b序列的编号。

每一次操作,一列(a,b数组)中相邻的两个数进行交换,其中ai和ai+1的交换等效于bi和bi+1的交换。我们可以固定a序列不动,修改b序列,最优的操作满足操作次数最少。

b序列第i位的数要移到目标位置第vi位中,求出v序列。b序列的数的移动顺序是按照对应的v序列的数从小到大。当目标位置为第vi位对应的bi(原来)需要移动时,前面的第1~vi-1位已经排好,而其它bi(原来)前面的数为还未移动的数,即对应的v序列的值大于vi。所以bi(原来)需要向左移动的次数为满足j<i and vj>vi所有的j的个数。

即总的操作次数为v序列的逆序对的个数。有两种方法求逆序对使得时间复杂度为O(nlogn):

1.归并排序+统计

2.离散化+树状数组

Code:

 #include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define yu 99999997
#define maxn 100000
 
struct node
{
    long value,pos;
}a[maxn+],b[maxn+];
long v[maxn+],t[maxn+],ans;
 
int cmp(const void *a,const void *b)
{
    if ((*(struct node *)a).value<(*(struct node *)b).value)
        return -;
    else
        return ;
}
 
void mergesort(long l,long r)
{
    if (l==r)
        return ;
    long mid,x,y,z,i;
    mid=(l+r)/;
    mergesort(l,mid);
    mergesort(mid+,r);
    for (i=l;i<=r;i++)
        t[i]=v[i];
    x=l;
    y=mid+;
    z=l;
    while (x<=mid && y<=r)
    {
        //两个数相等时让左边的数先加,因为相同的数不能凑成一对
        if (t[x]<=t[y])
        {
            v[z]=t[x];
            x++;
            //v[x] > v[mid+1]~v[y-1]
            ans=(ans+(y-mid-))%yu;
        }
        else if (t[x]>t[y])
        {
            v[z]=t[y];
            y++;
        }
        z++;
    }
    if (x<=mid)
    {
        //v[x] > v[mid+1]~v[r]
        ans=(ans+(mid-x+)*(r-mid))%yu;
        while (z<=r)
        {
            v[z]=t[x];
            x++;
            z++;
        }
    }
    else
    {
        while (z<=r)
        {
            v[z]=t[y];
            y++;
            z++;
        }
    }
}
 
int main()
{
    long n,i;
    scanf("%ld",&n);
    for (i=;i<=n;i++)
    {
        scanf("%ld",&a[i].value);
        a[i].pos=i;
    }
    for (i=;i<=n;i++)
    {
        scanf("%ld",&b[i].value);
        b[i].pos=i;
    }
    qsort(a+,n,sizeof(struct node),cmp);
    qsort(b+,n,sizeof(struct node),cmp);
    for (i=;i<=n;i++)
        v[b[i].pos]=a[i].pos;
    ans=;
    mergesort(,n);
    printf("%ld\n",ans);
    return ;
}
/*
Input:
10
10 1 5 2 7 4 9 3 6 8
7 5 1 8 10 4 6 2 3 9
Output:
18
*/

感慨一下:想当初比赛做这道题,没有想到是逆序对,最终没有做出来,留下遗憾。现在终于写了个题解,把这道题做了,算是对遗憾的一种弥补吧。
希望自己可以走得更远……

noip2013火柴排队_Solution的更多相关文章

  1. LOJ2609. NOIP2013 火柴排队 【树状数组】

    LOJ2609. NOIP2013 火柴排队 LINK 题目大意: 给你两个数列,定义权值∑i=1(ai−bi)^2 问最少的操作次数,最小化权值 首先需要发现几个性质 最小权值满足任意i,j不存在a ...

  2. [树状数组+逆序对][NOIP2013]火柴排队

    火柴排队 题目描述 涵涵有两盒火柴,每盒装有n根火柴,每根火柴都有一个高度.现在将每盒中的火柴各自排成一列,同一列火柴的高度互不相同,两列火柴之间的距离定义为:∑ (ai-bi)2,i=1,2,3,. ...

  3. NOIP2013火柴排队[逆序对]

    题目描述 涵涵有两盒火柴,每盒装有 n 根火柴,每根火柴都有一个高度. 现在将每盒中的火柴各自排成一列, 同一列火柴的高度互不相同, 两列火柴之间的距离定义为: ∑(ai-bi)^2 其中 ai 表示 ...

  4. [NOIP2013] 火柴排队(归并排序)

    题目描述 涵涵有两盒火柴,每盒装有 n 根火柴,每根火柴都有一个高度. 现在将每盒中的火柴各自排成一列, 同一列火柴的高度互不相同, 两列火柴之间的距离定义为: ∑(ai-bi)^2 其中 ai 表示 ...

  5. noip2013 火柴排队

    题目描述 涵涵有两盒火柴,每盒装有 n 根火柴,每根火柴都有一个高度. 现在将每盒中的火柴各自排成一列, 同一列火柴的高度互不相同, 两列火柴之间的距离定义为: ∑(ai-bi)^2 其中 ai 表示 ...

  6. jzoj[1438]NOIP2013火柴排队

    读题: 相邻两个火柴可以交换?两个火柴序列?嗅到了归并排序的味道. 读完题目之后,我们可以知道,如果想要交换次数最少,可以先固定一个序列不变,比如说a序列不变,变b序列 样例是 4 2 3 1 4 3 ...

  7. NOIP2013火柴排队

    Solution 恕我直言,这题是真的坑. 对于这道题,一个很显然的思路是对于A B两个序列,他们交换完后相对的两个数在原序列中的相对大小是相同的,于是我们就把序列按照A排序,在把B离散化,求逆序对, ...

  8. NOIp2013 火柴排队【逆序对/思维】 By cellur925

    题目大意:给你两列数\(ai\)和\(bi\),你可以交换每列数中相邻的两个数,求一个最小交换次数使\(\sum_{i=1}^{n}(a_i-b_i)^2\) 最小. 最后满足条件的两个序列一定是各个 ...

  9. NOIP 2013 火柴排队

    洛谷 P1966 火柴排队 洛谷传送门 JDOJ 2227: [NOIP2013]火柴排队 D1 T2 JDOJ传送门 Description 涵涵有两盒火柴,每盒装有 n 根火柴,每根火柴都有一个高 ...

随机推荐

  1. 系统重启后DNS地址默认修改修改引起的一次事故(Tomcat报错:java.net.UnknownHostException)

    事故描述:公司的一个内部业务系统由于程序bug,导致系统崩溃,需要强制重启服务器.系统重启后,赶紧将业务程序启动.随后发现/etc/resolv.conf文件的DNS地址被修改成了默认地址.发现之后, ...

  2. NTP系统时间同步-操作记录

    在初始化一台linux服务器后,发现这台服务器的时间不对[root@dev ~]# date2016年 10月 11日 星期二 07:04:34 CST Linux时钟分为系统时钟 (System C ...

  3. python之requests

    发送请求 导入 Requests 模块: >>> import requests >>> r = requests.get('https://xxxxxxx.jso ...

  4. 【个人博客作业II】代码复审结果

    [代码复审结果] General Does the code work? Does it perform its intended function, the logic is correct etc ...

  5. 面向对象课程 - 寒假第四次作业 - C++计算器项目计算部分

    C++计算器项目计算部分 零.项目源文件地址 地址:Calculator 2.0 一.项目信息相关 项 目 : Calculator 版 本 : 2 . 0 日 期 : 2016 . 4 . 14 实 ...

  6. jquery judge element exist

    http://learn.jquery.com/using-jquery-core/faq/how-do-i-test-whether-an-element-exists/ if ( $( " ...

  7. jQuery中empty与html("")的区别对比

    简单的说empty,首先循环给后代元素移除绑定(释放内存).清除jquery给此dom的cache,然后循环removeFirstChild,而html(''),则是简单暴力的设置innerHTML ...

  8. [转帖]super-inspire

    quickStart/快速开始 访问临时服务器地址, 你可以在这里选择一个喜欢的系统, 然后系统将自动创建该系统的容器, 并自动打开新的网页进入 web shell 交互. 目前支持 Ubuntu14 ...

  9. [小知识] 关闭我的电脑里面的百度网盘以及修改win+e快捷键打开我的电脑

    1. 登录百度云盘客户端 设置->基本->取消在我的电脑中显示百度网盘 2. 修改win+e的默认显示 打开我的电脑. 选择查看-选项 文件夹选项修改为: 此电脑即可..

  10. Spring MVC @ModelAttribute注解

    在一个Controller内,被@ModelAttribute标注的方法会在此controller的每个handler方法执行前被执行. 被@ModelAttribute标注的方法的参数绑定规则和普通 ...