[Luogu P2507] [BZOJ 1237] [SCOI2008]配對
阿新 • • 發佈:2018-12-15
洛谷傳送門
題目描述
你有 個整數和 個整數。你需要把它們配對,即每個恰好對應一個。要求所有配對的整數差的絕對值之和儘量小,但不允許兩個相同的數配對。例如,,則最優配對方案是,配對整數的差的絕對值分別為,和為。注意,是不允許的,因為相同的數不許配對。
輸入輸出格式
輸入格式:
第一行為一個正整數,接下來是 行,每行兩個整數和,保證所有
各不相同,也各不相同。
輸出格式:
輸出一個整數,即配對整數的差的絕對值之和的最小值。如果無法配對,輸出。
輸入輸出樣例
輸入樣例#1:
3
3 65
45 10
60 25
輸出樣例#1:
32
輸入樣例#2:
3
5 5
6 7
8 8
輸出樣例#2:
5
說明
30%的資料滿足:
100%的資料滿足:,和均為到之間的整數。
解題分析
如果排序後兩兩對應不同, 顯然對應匹配最好。
當我們發現排序後的時候, 顯然我們只會考慮和其相鄰的兩個數交換匹配的情況(因為交換的越多越不優), 所以我們一遍考慮相鄰三個數就好。
程式碼如下:
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cctype>
#include <algorithm>
#include <cmath>
#define R register
#define IN inline
#define W while
#define gc getchar()
#define INF 100000000000ll
#define MX 100050
#define ll long long
template <class T>
IN void in(T &x)
{
x = 0; R char c = gc;
for (; !isdigit(c); c = gc);
for (; isdigit(c); c = gc)
x = (x << 1) + (x << 3) + c - 48;
}
using namespace std;
IN ll judge(R int a, R int b) {return a == b ? INF : abs(a - b);}
int n;
ll dp[MX], a[MX], b[MX];
int main(void)
{
in(n);
for (R int i = 1; i <= n; ++i) in(a[i]), in(b[i]);
sort(a + 1, a + 1 + n), sort(b + 1, b + 1 + n);
if(n == 1 && a[1] == b[1]) return puts("-1"), 0;
dp[1] = judge(a[1], b[1]);
dp[2] = min(dp[1] + judge(a[2], b[2]), judge(a[1], b[2]) + judge(a[2], b[1]));
for (R int i = 3; i <= n; ++i)
{
dp[i] = dp[i - 1] + judge(a[i], b[i]);
dp[i] = min(dp[i], dp[i - 2] + judge(a[i - 1], b[i]) + judge(a[i], b[i - 1]));
dp[i] = min(dp[i], dp[i - 3] + judge(a[i - 1], b[i - 2]) + judge(a[i], b[i - 1]) + judge(a[i - 2], b[i]));
dp[i] = min(dp[i], dp[i - 3] + judge(a[i], b[i - 2]) + judge(a[i - 2], b[i - 1]) + judge(a[i - 1], b[i]));
dp[i] = min(dp[i], dp[i - 3] + judge(a[i], b[i - 2]) + judge(a[i - 1], b[i - 1]) + judge(a[i - 2], b[i]));
}
printf("%lld", dp[n]);
}