[SCOI2008]配对 (贪心,动态规划)

题目链接

Solution

很妙的DP,很妙的贪心.

首先考虑,如果说没有那个相同的不能配对的情况;
那么我们肯定是直接排两遍序,然后一一对应即可.

但是是有限制的,同时我们可得几个条件供贪心:

  • 每个数字仅在 \(a\) 或 \(b\) 中出现一次. 即每个序列排序之后满足 \(a_i≠b_i\).
  • 如果 \(a_i=b_i\) ,我们需要去和其他位置的元素交换;
  • 我们交换的元素与当前元素的绝对距离不会大于 \(2\),也就是说每次我们碰到相同的情况,只需要 \(a_i\) 与 \(a_{i+1}\) 或者 \(a_{i-1}\) 交换.

然后我们定义 \(f[i]\) 为到第 \(i\) 个点的时候最小的差值.
考虑3个一组转移,至于为什么是3个,可以看上面的贪心条件.
令原排列为 \(a[i-2],a[i-1],a[i]\);
则有以下几种情况:

  1. \(a[i-2],a[i],a[i-1]\)
  2. \(a[i-1],a[i-2],a[i]\)
  3. \(a[i-1],a[i],a[i-2]\)
  4. \(a[i],a[i-2],a[i-1]\)
  5. \(a[i],a[i-1],a[i-2]\)

然后我们每次通过讨论从 \(f[i-3]\) 转移过来即可.
注意要预先处理 \(f[1],f[2],f[3]\) 的值.

Code

#include<bits/stdc++.h>
#define maxn 100005
#define ll long long
using namespace std;
const ll Inf=19260817;
ll f[maxn],n,a[maxn],b[maxn];
ll cal(int x,int y)
{
    if (a[x]==b[y]) return Inf;
    return abs(a[x]-b[y]);
}
int main()
{
   scanf("%d",&n);
   for (int i=1;i<=n;i++) scanf("%d%d",&a[i],&b[i]);
   sort(a+1,a+n+1);
   sort(b+1,b+n+1);
   for (int i=1;i<=n;i++) f[i]=Inf;
   f[0]=0;
   for (int i=1;i<=n;i++)
   {
     ll t=inf;
     if (i>=1) t=min(t,f[i-1]+cal(i,i));
     if (i>=2) t=min(t,f[i-2]+cal(i,i-1)+cal(i-1,i));
     if (i>=3) t=min(t,f[i-3]+cal(i,i-1)+cal(i-1,i-2)+cal(i-2,i)),
     t=min(t,f[i-3]+cal(i-2,i-1)+cal(i-1,i)+cal(i,i-2));
     f[i]=t;
   }
   printf("%lld\n",f[n]);
}

原文地址:https://www.cnblogs.com/Kv-Stalin/p/9379865.html

时间: 2024-08-30 08:22:31

[SCOI2008]配对 (贪心,动态规划)的相关文章

贪心 &amp; 动态规划

相同点: 贪心算法和dp都是一种递推算法,是一种解题的思想 都是由局部最优解来推导全局最优解 不同点: 贪心算法: 1.贪心算法中,作出的每步贪心决策都无法改变,因为贪心策略是由上一步的最优解推导下一步的最优解,而上一部之前的最优解则不作保留. 2.由(1)中的介绍,可以知道贪心法正确的条件是:每一步的最优解一定包含上一步的最优解 3.求最小生成树的Prim算法和Kruskal算法都是漂亮的贪心算法.背包问题. 动态规划: 1.全局最优解中一定包含某个局部最优解,但不一定包含前一个局部最优解,因

Bzoj1237 [SCOI2008]配对

Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 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是不允许的,因 为

[SCOI2008]配对

题目描述 你有 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是不允许的,因为相同的数不许配对. 输入输出格式 输入格式: 第一行为一个正整数n,接下来是n 行,每行两个整数Ai和Bi,保证所有 Ai各不相同,Bi也各不相同. 输

codeforces 某套题s : surf(贪心 || 动态规划)

题目: Now that you've come to Florida and taken up surfing, you love it! Of course, you've realized that if you take a particular wave, even if it's very fun, you may miss another wave that's just about to come that's even more fun. Luckily, you've got

[ZJOI2005]午餐 (贪心,动态规划)

题目描述 上午的训练结束了,THU ACM小组集体去吃午餐,他们一行N人来到了著名的十食堂.这里有两个打饭的窗口,每个窗口同一时刻只能给一个人打饭.由于每个人的口味(以及胃口)不同,所以他们要吃的菜各有不同,打饭所要花费的时间是因人而异的.另外每个人吃饭的速度也不尽相同,所以吃饭花费的时间也是可能有所不同的. THU ACM小组的吃饭计划是这样的:先把所有的人分成两队,并安排好每队中各人的排列顺序,然后一号队伍到一号窗口去排队打饭,二号队伍到二号窗口去排队打饭.每个人打完饭后立刻开始吃,所有人都

1237: [SCOI2008]配对

Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1789  Solved: 715[Submit][Status][Discuss] 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,和为

洛谷 P2507 [SCOI2008]配对

传送门 (讲道理)一道很简单的题,可惜我实在zz到了一种境界. 首先都可以匹配的情况下,两个数组分别排个序对应匹配肯定是最优的,实在太蠢的我不知道如何证明,就画了个丑陋的图. 可以发现不交叉一定不会更劣. 然后有一些是不能匹配的情况下,容易想到到肯定是跟它附近的几个交换.发现最多也不会跟它距离超过2的匹配,如图: 若是D和E匹配,一定不是最优. 考虑把三把叉中的一把拆掉,最坏情况下,A,B,C中的一个等于E,不能换,D等于另一个F,G,H中的一个,不能换,也就是两个交叉的可能都无法拆,但是是三个

AtCoder Grand Contest 026 (AGC026) E - Synchronized Subsequence 贪心 动态规划

原文链接 题目传送门 - AGC026E 题意 给定一个长度为 $2n$ 的字符串,包含 $n$ 个 $'a'$ 和 $n$ 个 $'b'$ . 现在,让你按照原顺序取出一些字符,按照原顺序组成新的字符串,输出所有满足条件的字符串中字典序最大的?(字典序: $b>a>""$) 条件限制:当且仅当取了原序列的第 $i$ 个 $'a'$ 时,原序列的第 $i$ 个 $'b'$ 也被取了. $n\leq 3000$ 题解 代码 #include <bits/stdc++.h

编程题目分类(剪辑)

1. 编程入门 2. 数据结构 3. 字符串 4. 排序 5. 图遍历 6. 图算法 7. 搜索:剪枝,启发式搜索 8. 动态规划/递推 9. 分治/递归 10. 贪心 11. 模拟 12. 算术与代数 13. 组合问题 14. 数论 15. 网格,几何,计算几何 [编程入门] PC 110101, uva 100, The 3n+1 problem, 难度 1 PC 110102, uva 10189, Minesweeper, 难度 1 PC 110103, uva 10137, The T