洛谷P2507 [SCOI2008]配对 题解(dp+贪心)

标签:题解

阅读体验:https://zybuluo.com/Junlier/note/1299251

链接题目地址:洛谷P2507 [SCOI2008]配对

感觉是道很好的推断题

贪心

想到贪心的结论就很容易,没想到就很难做出来了

结论:对\(A,B\)数组分别排序之后,在\(A\)中选第\(i\)个数,与之配对的数一定在\(B[i-1]\)~\(B[i+1]\)内

其实证明是很好证的,在与你是否往这方面想了。。。

因为题目有一个很好的性质:\(A,B\)数列中数字各不相同

所以如果没有配对不相等的限制的话,我们肯定是排序直接减得答案是吧

那么有限制之后,就有机会让\(A[i]\)和\(B[i-1]\)或\(B[i+1]\)配对了吧,跳远了显然是不会更优的

动态规划

那么就可以直接\(dp\)了:\(dp[i]\)表示到第\(i\)号全部配对的最小答案

因为一个数可能与三个数配对,那么我们可以大力讨论\(dp\)了

对于限制,我们手写一个\(ABS\),如果差为0,返回\(Inf\)就\(ok\)

dp[i]=MIN(dp[i],dp[i-1]+ABS(A[i]-B[i]));
dp[i]=MIN(dp[i],dp[i-2]+ABS(A[i]-B[i-1])+ABS(A[i-1]-B[i]));
dp[i]=MIN(dp[i],dp[i-3]+ABS(A[i]-B[i-1])+ABS(A[i-1]-B[i-2])+ABS(A[i-2]-B[i]));
dp[i]=MIN(dp[i],dp[i-3]+ABS(A[i]-B[i-2])+ABS(A[i-1]-B[i-1])+ABS(A[i-2]-B[i]));
dp[i]=MIN(dp[i],dp[i-3]+ABS(A[i]-B[i-2])+ABS(A[i-1]-B[i])+ABS(A[i-2]-B[i-1]));

从上到下依次是:自己看一下吧。。。(草稿纸上玩结论,自己\(yy\),我懒得写了)

那么全部代码

不合法情况就是\(n==1\)并且\(A[1]==B[1]\)时

因为\(A,B\)数列中数字各不相同,所以\(n>1\)时一定可以另外配得到对

#include<bits/stdc++.h>
#define il inline
#define rg register
#define ldb double
#define lst long long
#define rgt register int
#define N 100050
using namespace std;
const lst Inf=1e15;
il int MAX(rgt x,rgt y){return x>y?x:y;}
il lst MIN(rg lst x,rg lst y){return x<y?x:y;}
il int read()
{
int s=0,m=0;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')m=1;ch=getchar();}
while( isdigit(ch))s=(s<<3)+(s<<1)+(ch^48),ch=getchar();
return m?-s:s;
} int n;
lst A[N],B[N];lst dp[N];
il lst ABS(rg lst x){return x?(x>0?x:-x):(Inf);} int main()
{
n=read();
for(rgt i=1;i<=n;++i)A[i]=read(),B[i]=read(),dp[i]=Inf;
if(n==1&&A[1]==B[1]){puts("-1");return 0;}
sort(&A[1],&A[n+1]),sort(&B[1],&B[n+1]);
dp[1]=ABS(A[1]-B[1]);
dp[2]=MIN(dp[1]+ABS(A[2]-B[2]),ABS(A[1]-B[2])+ABS(A[2]-B[1]));
for(rgt i=3;i<=n;++i)
{
dp[i]=MIN(dp[i],dp[i-1]+ABS(A[i]-B[i]));
dp[i]=MIN(dp[i],dp[i-2]+ABS(A[i]-B[i-1])+ABS(A[i-1]-B[i]));
dp[i]=MIN(dp[i],dp[i-3]+ABS(A[i]-B[i-1])+ABS(A[i-1]-B[i-2])+ABS(A[i-2]-B[i]));
dp[i]=MIN(dp[i],dp[i-3]+ABS(A[i]-B[i-2])+ABS(A[i-1]-B[i-1])+ABS(A[i-2]-B[i]));
dp[i]=MIN(dp[i],dp[i-3]+ABS(A[i]-B[i-2])+ABS(A[i-1]-B[i])+ABS(A[i-2]-B[i-1]));
}return printf("%lld\n",dp[n]),0;
}

洛谷P2507 [SCOI2008]配对 题解(dp+贪心)的更多相关文章

  1. 洛谷 P2507 [SCOI2008]配对

    P2507 [SCOI2008]配对 题目背景 四川NOI2008省选 题目描述 你有 n 个整数Ai和n 个整数Bi.你需要把它们配对,即每个Ai恰好对应一个Bp[i].要求所有配对的整数差的绝对值 ...

  2. 洛谷P2507 [SCOI2008]配对 [DP,贪心]

    题目传送门 配对 题目描述 你有 n 个整数Ai和n 个整数Bi.你需要把它们配对,即每个Ai恰好对应一个Bp[i].要求所有配对的整数差的绝对值之和尽量小,但不允许两个相同的数配对.例如A={5,6 ...

  3. 洛谷P2507 [SCOI2008]配对

    题目背景 四川NOI2008省选 题目描述 你有 n 个整数Ai和n 个整数Bi.你需要把它们配对,即每个Ai恰好对应一个Bp[i].要求所有配对的整数差的绝对值之和尽量小,但不允许两个相同的数配对. ...

  4. 【题解】洛谷P2577 [ZJOI2005] 午餐(DP+贪心)

    次元传送门:洛谷P2577 思路 首先贪心是必须的 我们能感性地理解出吃饭慢的必须先吃饭(结合一下生活) 因此我们可以先按吃饭时间从大到小排序 然后就能自然地想到用f[i][j][k]表示前i个人在第 ...

  5. 洛谷 P2577 [ ZJOI 2005 ] 午餐 —— DP + 贪心

    题目:https://www.luogu.org/problemnew/show/P2577 首先,想一想可以发现贪心策略是把吃饭时间长的人放在前面: 设 f[i][j] 表示考虑到第 i 个人,目前 ...

  6. 洛谷P5019 铺设道路 题解 模拟/贪心基础题

    题目链接:https://www.luogu.org/problemnew/show/P5019 这道题目是一道模拟题,但是它有一点贪心的思想. 我们假设当前最大的深度是 \(d\) ,那么我们需要把 ...

  7. 洛谷P2756飞行员配对方案问题 P2055假期的宿舍【二分图匹配】题解+代码

    洛谷 P2756飞行员配对方案问题 P2055假期的宿舍[二分图匹配] 飞行员配对方案问题 题目背景 第二次世界大战时期.. 题目描述 英国皇家空军从沦陷国征募了大量外籍飞行员.由皇家空军派出的每一架 ...

  8. 【洛谷】P1052 过河【DP+路径压缩】

    P1052 过河 题目描述 在河上有一座独木桥,一只青蛙想沿着独木桥从河的一侧跳到另一侧.在桥上有一些石子,青蛙很讨厌踩在这些石子上.由于桥的长度和青蛙一次跳过的距离都是正整数,我们可以把独木桥上青蛙 ...

  9. 洛谷 P2503 [HAOI2006]均分数据 随机化贪心

    洛谷P2503 [HAOI2006]均分数据(随机化贪心) 现在来看这个题就是水题,但模拟赛时想了1个小时贪心,推了一堆结论,最后发现贪心做 不了, 又想了半个小时dp 发现dp好像也做不了,在随机化 ...

随机推荐

  1. contenteditable 光标定位到最后

    在Vue做项目时,做了一个div[contenteditable=true]的组件作为文本输入框 在非手动输入值后,光标会丢失,经测试以下这段代码可用,直接将光标定位到最后 function keep ...

  2. 【leetcode】Find Largest Value in Each Tree Row

    You need to find the largest value in each row of a binary tree. Example: Input: 1 / \ 3 2 / \ \ 5 3 ...

  3. 17.树的子结构(python)

    题目描述 输入两棵二叉树A,B,判断B是不是A的子结构.(ps:我们约定空树不是任意一个树的子结构) class Solution: def HasSubtree(self, pRoot1, pRoo ...

  4. 数据库导出数据到excel格式

    场景: 由于业务人员经常会找DBA导出一些数据,写了一个自动导出脚本. import pymysql from openpyxl import Workbook from openpyxl.write ...

  5. 如何查看运行的docker container 的 执行 docker run的命令

    前言 就是我备份了一下 mysql_container, 然后我想启用 新的备份的mysql_container 但是之前的docker run image xxxxxx这些都已经忘记了 我想找一下之 ...

  6. input样式去掉苹果手机的默认样式

    /*<!---->去掉苹果短的样式*/ input[type="button"], input[type="submit"], input[type ...

  7. [BZOJ3796]Mushroom追妹纸:后缀自动机+KMP

    分析 这道题有个\(O(n)\)的后缀自动机做法,感觉很好理解就在这说一下. 先对\(s1\)和\(s2\)求最长公共子串,对于\(s2\)的每一个下标\(i\),求一个\(f[i]\)表示以\(s2 ...

  8. Redis、Nginx加入启动命令

    1.redis加入系统启动命令 vim /etc/init.d/redis #!/bin/sh #chkconfig: 2345 80 90 # Simple Redis init.d script ...

  9. ffplay播放YUV数据

    播放器YUV系列的格式用ffplay很方便 免费的 播放NV21 ffplay -i d:/cap.yuv -pix_fmt nv21 -s 640x480 播放YUV420P ffplay -i d ...

  10. object Object {} any unknown

    object: 除了primitive(boolean null number string undefined bigint symbol)的类型 Object: Object和any很像 ,Obj ...