BZOJ1237: [SCOI2008]配对
题意:给定两个数组 构造一个配对 使得每个位置上之差的和最小 大小相同的不能配对
题解:猜了一下 应该把两个数组排序一下 答案最小
处理相同的不能配对的时候 那么应该找就近的交换
猜一下 如果有合法方案的话 肯定一个大小为3的环就能解决配对问题了
#include <bits/stdc++.h> using namespace std; typedef long long ll; const ll INF = 1e12; int q[100005]; int w[100005]; ll dp[100005]; ll abss(ll x, ll y) { if(x == y) return INF; else if(x > y) return x - y; else if(x < y) return y - x; } int main() { dp[0] = 0; int n; scanf("%d", &n); for(int i = 1; i <= n; i++) scanf("%d%d", &q[i], &w[i]), dp[i] = INF; sort(q + 1, q + 1 + n); sort(w + 1, w + 1 + n); for(int i = 1; i <= n; i++) { if(i >= 1 && dp[i - 1] != INF) { //if(i == 3) cout<<"hi"<<endl; ll x = abss(q[i], w[i]); dp[i] = min(dp[i], dp[i - 1] + x); //if(i == 3) cout<<dp[i]<<endl; } if(i >= 2 && dp[i - 2] != INF) { ll x1 = abss(q[i], w[i - 1]); ll x2 = abss(q[i - 1], w[i]); dp[i] = min(dp[i], dp[i - 2] + x1 + x2); //if(i == 3) cout<<dp[i]<<endl; } if(i >= 3 && dp[i - 3] != INF) { ll x1 = abss(q[i], w[i - 2]); ll y1 = abss(q[i - 1], w[i - 1]); ll y2 = abss(q[i - 2], w[i]); dp[i] = min(dp[i], dp[i - 3] + y1 + y2 + x1); ll z1 = abss(q[i - 1], w[i]); ll z2 = abss(q[i - 2], w[i - 1]); dp[i] = min(dp[i], dp[i - 3] + z1 + z2 + x1); ll o1 = abss(q[i], w[i - 1]); ll o2 = abss(q[i - 1], w[i - 2]); ll o3 = abss(q[i - 2], w[i]); dp[i] = min(dp[i], dp[i - 3] + o1 + o2 + o3); //if(i == 3) cout<<dp[i]<<endl; } } //for(int i = 1; i <= n; i++) cout<<dp[i]<<endl; if(dp[n] == INF) puts("-1"); else printf("%lld\n", dp[n]); return 0; }