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

Leohh發表於2017-10-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相交。交換後綠色線段總長變長,即花費變多。(其他情況同理)

    (圖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 }

 

相關文章