zoukankan      html  css  js  c++  java
  • Bzoj1237 [SCOI2008]配对

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 1446  Solved: 551

    Description

    你有n 个整数Ai和n 个整数Bi。你需要把它们配对,即每个Ai恰好对应一 个Bp[i]。要求所有配对的整数差的绝对值之和尽量小,但不允许两个相同的数配 对。例如A={5,6,8},B={5,7,8},则最优配对方案是5配8, 6配5, 8配7,配对整数 的差的绝对值分别为2, 2, 1,和为5。注意,5配5,6配7,8配8是不允许的,因 为相同的数不许配对。

    Input

    第一行为一个正整数n,接下来是n 行,每行两个整数Ai和Bi,保证所有 Ai各不相同,Bi也各不相同。

    Output

    输出一个整数,即配对整数的差的绝对值之和的最小值。如果无法配对,输 出-1。

    Sample Input

    3
    3 65
    45 10
    60 25

    Sample Output

    32

    HINT

    30%的数据满足:n <= 10^4 100%的数据满足:1 <= n <= 10^5,Ai和Bi均为1到106之间的整数。

    Source

    动态规划 线性DP 结论题

    结论题,有趣。

    如果没有匹配数不能相同的限制,分别将两数组排序,依次贪心匹配即可。

    加上限制以后,匹配关系可能需要前后调整

    由于a和b数组各自没有相同元素,可以脑洞出一个神奇的结论:调整的位置不会超过三位。

    并不会证明。

    于是直接推过去即可。

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstdio>
     4 #include<cmath>
     5 #include<cstring>
     6 #define LL long long
     7 using namespace std;
     8 const int inf=1e9;
     9 const int mxn=100010;
    10 int read(){
    11     int x=0,f=1;char ch=getchar();
    12     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    13     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
    14     return x*f;
    15 }
    16 inline int CP(int a,int b){return (a==b)?inf:abs(a-b);}
    17 int n;
    18 int a[mxn],b[mxn];
    19 LL f[mxn];
    20 int main(){
    21 //    freopen("in.txt","r",stdin);
    22     int i,j;
    23     n=read();
    24     for(i=1;i<=n;i++){
    25         a[i]=read();b[i]=read();
    26     }
    27     sort(a+1,a+n+1);sort(b+1,b+n+1);
    28     memset(f,0x3f,sizeof f);
    29     f[0]=0;
    30     f[1]=CP(a[1],b[1]);
    31     f[2]=min(CP(a[1],b[1])+CP(a[2],b[2]),CP(a[1],b[2])+CP(a[2],b[1]));
    32     for(i=3;i<=n;i++){
    33         f[i]=min(f[i-1]+CP(a[i],b[i]),f[i-2]+CP(a[i-1],b[i])+CP(a[i],b[i-1]));
    34         f[i]=min(f[i],f[i-3]+CP(a[i],b[i-1])+CP(a[i-1],b[i-2])+CP(a[i-2],b[i]));
    35         f[i]=min(f[i],f[i-3]+CP(a[i],b[i-2])+CP(a[i-1],b[i-1])+CP(a[i-2],b[i]));
    36         f[i]=min(f[i],f[i-3]+CP(a[i],b[i-2])+CP(a[i-1],b[i])+CP(a[i-2],b[i-1]));
    37     }
    38     if(f[n]>=0x3f3f3f3f3f3f3f)f[n]=-1;
    39     printf("%lld
    ",f[n]);
    40     return 0;
    41 }
  • 相关阅读:
    SpringBoot与quartz集成
    SpringBoot 中使用 @Valid 注解 + Exception 全局处理器优雅处理参数验证
    搭建Redis集群和MySQL主从同步
    scanf_s读取键盘输入字符串失败
    含有通配符*的字符匹配(C语言)
    人之患
    TCP socket编程记录(C语言)
    程序变量命名规范(个人)
    h lib dll文件相关部分
    关于inet_ntop、inet_pton中的n和p分别代表的意义
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/6925952.html
Copyright © 2011-2022 走看看