hihoCoder#1838 : 鎕鎕鎕 贪心

~~~题面~~~

题解:

  神奇的贪心题,,,感觉每次做贪心题都无从下手。。。

  我们首先按照a对所有卡片从小到大排序,然后从1开始,从连续的两张牌中取b最大的,最后一张单出来的也取了。

  可以证明,这样的方案一定是合法的。

  为什么呢?

  假设我们将排序后的牌按照(1, 2) (3, 4) ……这样的方式两两分组,那么既然我们每次都是取b最大的那张,b的限制显然我们已经满足了。

  现在来考虑a,假设我们遇到了最坏的情况,在每一组里面,我们都取到了a最小的那个,即我们取到了第1, 3, 5,……张牌(因为已经排好序了,所以a最小的一定是这些),那么这个时候我们可以改变一下分组方式由原来的(1, 2) (3, 4) ……变成1, (2, 3), (4, 5) ……(2 * n, 2 * n + 1),那么你可以发现,这时我们取的牌就变成了任意组当中a最大的那张,因此a也是满足条件的。

  证明完毕。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define R register int 
 4 #define AC 210000
 5 
 6 int n;
 7 
 8 struct card{
 9     int a, b, id;
10 }s[AC];
11 
12 inline bool cmp(card x, card y)
13 {
14     return x.a < y.a;
15 }
16 
17 inline int read()
18 {
19     int x = 0;char c = getchar();
20     while(c > '9' || c < '0') c = getchar();
21     while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
22     return x;
23 }
24 
25 void pre()
26 {
27     n = read();
28     int b = 2 * n + 1;
29     for(R i = 1; i <= b; i ++) 
30         s[i].a = read(), s[i].b = read(), s[i].id = i;
31     sort(s + 1, s + b + 1, cmp);
32 }
33 
34 void work()
35 {
36     int b = 2 * n;
37     for(R i = 1; i <= b; i += 2)
38     {
39         if(s[i].b > s[i + 1].b) printf("%d
", s[i].id);
40         else printf("%d
", s[i + 1].id);
41     }
42     printf("%d
", s[2 * n + 1].id);
43 }
44 
45 int main()
46 {
47     freopen("in.in", "r", stdin);
48     pre();
49     work();
50     fclose(stdin);
51     return 0;
52 }
View Code
原文地址:https://www.cnblogs.com/ww3113306/p/9806992.html