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 }

 

posted @ 2017-10-11 00:30  Leohh  阅读(705)  评论(0编辑  收藏  举报