BZOJ 3399 [Usaco2009 Mar]Sand Castle城堡:贪心【最小匹配代价】
题目链接: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相交。交换后绿色线段总长变长,即花费变多。(其他情况同理)
(图1) (图2)
综上:如果a,b按照升序排列,总花费只可能更少。
AC Code:
1 #include <iostream> 2 #include <stdio.h> 3 #include <string.h> 4 #include <algorithm> 5 #define MAX_N 25005 6 7 using namespace std; 8 9 int n,x,y; 10 int ans=0; 11 int a[MAX_N]; 12 int b[MAX_N]; 13 14 void read() 15 { 16 cin>>n>>x>>y; 17 for(int i=0;i<n;i++) 18 { 19 cin>>a[i]>>b[i]; 20 } 21 } 22 23 void solve() 24 { 25 sort(a,a+n); 26 sort(b,b+n); 27 for(int i=0;i<n;i++) 28 { 29 if(a[i]<b[i]) ans+=(b[i]-a[i])*x; 30 else ans+=(a[i]-b[i])*y; 31 } 32 } 33 34 void print() 35 { 36 cout<<ans<<endl; 37 } 38 39 int main() 40 { 41 read(); 42 solve(); 43 print(); 44 }