• 解题:SCOI 2008 配对


    题面

    如果没有两个数不能相同这个限制就两个数组排序后贪心即可。现在加上这个限制,注意到每个数组中的数是两两不同的,所以每次一定能在前面或后面一个数中找一个换过来,这样每次考虑相邻三个数转移就可以了,注意特判一下边界。

     1 #include<cmath>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 const int N=100005;
     7 long long a[N],b[N],dp[N],n,ans;
     8 inline long long diff(long long a,long long b)
     9 {
    10     return (a==b)?1e12:abs(a-b);
    11 }
    12 inline long long mini(long long a,long long b)
    13 {
    14     return a<b?a:b;
    15 }
    16 int main ()
    17 {
    18     scanf("%lld",&n);
    19     for(int i=1;i<=n;i++)
    20         scanf("%lld%lld",&a[i],&b[i]);
    21     sort(a+1,a+1+n),sort(b+1,b+1+n);
    22     if(a[1]==b[1]&&n==1) {printf("-1"); return 0;}
    23     memset(dp,0x3f,sizeof dp),dp[0]=0;
    24     dp[1]=mini(dp[1],diff(a[1],b[1]));
    25     dp[2]=mini(dp[2],dp[1]+diff(a[2],b[2]));
    26     dp[2]=mini(dp[2],dp[0]+diff(a[1],b[2])+diff(a[2],b[1]));
    27     for(int i=3;i<=n;i++)
    28     {
    29         dp[i]=mini(dp[i],dp[i-1]+diff(a[i],b[i]));
    30         dp[i]=mini(dp[i],dp[i-2]+diff(a[i-1],b[i])+diff(a[i],b[i-1]));
    31         dp[i]=mini(dp[i],dp[i-3]+diff(a[i-2],b[i])+diff(a[i-1],b[i-1])+diff(a[i],b[i-2]));
    32         dp[i]=mini(dp[i],dp[i-3]+diff(a[i-2],b[i])+diff(a[i-1],b[i-2])+diff(a[i],b[i-1]));
    33         dp[i]=mini(dp[i],dp[i-3]+diff(a[i-2],b[i-1])+diff(a[i-1],b[i])+diff(a[i],b[i-2]));
    34      }
    35      printf("%lld",dp[n]);
    36     return 0;
    37 } 
    View Code
  • 相关阅读:
    BZOJ3105-新Nim游戏
    POJ2947-Widget Factory
    POJ2248-Addition Chains
    POJ1964-City Game
    POJ2823-Sliding Window
    关于upx壳的一点认知,以及upx壳的特征识别
    易语言人脸识别算法源码
    易语言websocket客户端纯源码(无模块)
    易语言雷电模拟器批量虚拟定位源码
    易语言修改外部任意窗口标题图标源码
  • 原文地址:https://www.cnblogs.com/ydnhaha/p/9780180.html
Copyright © 2020-2023  润新知