BZOJ 3399 [Usaco2009 Mar]Sand Castle城堡:贪心【最小匹配代价】

时间:2022-12-30 23:42:11

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3399

题意:

  给你一个数列a,和一个可变换顺序的序列b(数列长度≤25000)。

  a增加一个单位代价为x,降低一个单位代价为y。

  求a变为b的最小代价。

题解:

  贪心。

  将a,b分别从小到大排序,然后统计答案。

  证明:

    因为a,b均为升序,所以对于交换a[i]和a[j],有四种情况:

    红色为a的走势,蓝色为b,绿色为花费。实线为交换之前,虚线为交换之后。

    (1)a,b不相交。交换前和交换后绿色线段总长不变,即花费不变。(其他情况同理)

    (2)a,b相交。交换后绿色线段总长变长,即花费变多。(其他情况同理)

    BZOJ 3399 [Usaco2009 Mar]Sand Castle城堡:贪心【最小匹配代价】(图1)        BZOJ 3399 [Usaco2009 Mar]Sand Castle城堡:贪心【最小匹配代价】(图2)

    综上:如果a,b按照升序排列,总花费只可能更少。

AC Code:

 #include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#define MAX_N 25005 using namespace std; int n,x,y;
int ans=;
int a[MAX_N];
int b[MAX_N]; void read()
{
cin>>n>>x>>y;
for(int i=;i<n;i++)
{
cin>>a[i]>>b[i];
}
} void solve()
{
sort(a,a+n);
sort(b,b+n);
for(int i=;i<n;i++)
{
if(a[i]<b[i]) ans+=(b[i]-a[i])*x;
else ans+=(a[i]-b[i])*y;
}
} void print()
{
cout<<ans<<endl;
} int main()
{
read();
solve();
print();
}