zoukankan      html  css  js  c++  java
  • 【NOIP2013】火柴排队 题解(贪心+归并排序)

    前言:一道水题。

    -----------------------

    题目链接

    题目大意:给出数列$a_i$和$b_i$,问使$sum_{i=1}^n (a_i-b_i)^2$最小的最少操作次数。

    首先,如果两个数列相同位置的数排名相同,那么符合题意。现在我们证明一下:

    证明:$a_i<a_j,b_i<b_j,(a_i-b_i)^2+(a_j-b_j)^2<(a_i-b_j)^2+(b_i-a_j)^2$

    $(a_i-b_j)^2+(b_i-a_j)^2=a_i^2+b_i^2+a_j^2+b_j^2-2a_ib_j-2b_ia_j$

    $(a_i-b_i)^2+(a_j-b_j)^2=a_i^2+b_i^2+a_j^2+b_j^2-2a_ib_i-2a_jb_j$

    上式减下式得:$2a_i(b_i-b_j)+2a_j(b_j-b_i)$

    $=2a_i(b_i-b_j)-2a_j(b_i-b_j)$

    $=2(a_i-a_j)(b_i-b_j)>0$

    所以$(a_i-b_i)^2+(a_j-b_j)^2<(a_i-b_j)^2+(b_i-a_j)^2$。

    证毕。

    计算次数的话就是比较新的位置和之前的位置,归并排序解决。其实就是归并排序求逆序对的变形。

    代码:

    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    const int mod=99999997;
    int n,c[1000005],r[1000005],ans;
    inline int read()
    {
        int x=0,f=1;char ch=getchar();
        while(!isdigit(ch)){
            if (ch=='-') f=-1;
            ch=getchar();
        }while(isdigit(ch)){
            x=x*10+ch-'0';
            ch=getchar();
        }
        return x*f;
    }
    struct node
    {
        int x,l;
    }a[1000005],b[1000005];
    bool cmp(node s,node y)
    {
        return s.x<y.x;
    }
    void msort(int l,int ri)
    {
        if (l>=ri) return;
        int mid=(l+ri)>>1;
        msort(l,mid);
        msort(mid+1,ri);
        int i,j,k;
        for (i=l,j=mid+1,k=l;i<=mid&&j<=ri;)
            if (c[i]>c[j])
            {
                ans=(ans+ri-j+1)%mod;
                r[k]=c[i];i++;k++;
            }
            else
            {
                r[k]=c[j];k++;j++;
            }
        for (;i<=mid;i++,k++) r[k]=c[i];    
        for (;j<=ri;j++,k++) r[k]=c[j];
        for (int s=l;s<=ri;s++) c[s]=r[s];
    }
    signed main()
    {
        n=read();
        for (int i=1;i<=n;i++) a[i].x=read(),a[i].l=i;
        for (int i=1;i<=n;i++) b[i].x=read(),b[i].l=i;
        sort(a+1,a+n+1,cmp);
        sort(b+1,b+n+1,cmp);
        for (int i=1;i<=n;i++) c[b[i].l]=a[i].l;
        msort(1,n);
        cout<<ans;
        return 0;
    } 
  • 相关阅读:
    java并发:简单面试问题集锦
    Java:泛型
    Java:注解(元数据)
    Java:反射
    Java:静态代理 and 动态代理
    华为机试题——该警醒了,骚年
    java并发:线程同步机制之Lock
    java并发:中断一个正在运行的线程
    java中String类型变量的赋值问题
    java中的自增问题
  • 原文地址:https://www.cnblogs.com/Invictus-Ocean/p/12995516.html
Copyright © 2011-2022 走看看