HDU/HDOJ 4864 Task

贪心题。

贪心方法很是naive......

首先我们就能注意到一个性质:优先选择时间(x)长的,然后才是等级(y)。

所以我们把机器和任务排好序,从大到小枚举任务。对于每一个x满足的机器,x也一定满足后面的任务。所以我们只关注y即可。

在所有x符合的机器中选择y最小的满足条件的机器即可。

怎么选出来这台机器呢?枚举是n^2,不可取。堆运气不好的情况下是n^2 * logn,更差。我只能想到splay.....

后来得到指点:你开个vis数组JINHI……C#@BP909uawmaUWrbn089w3w309r3907502%*&¥*……Xh

我一看范围:1440, 这显然就是正解。于是开一个sum数组表示y为sum的可用机器有多少台。

然后就A了!

 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <cstring>
 4 using std::pair;
 5 using std::sort;
 6 const int N = 100010, F = 1450;
 7 
 8 int sum[F];
 9 pair<int, int> ma[N], ta[N];
10 
11 int main() {
12     int n, m;
13     while(scanf("%d%d", &m, &n) != EOF) {
14         memset(sum, 0, sizeof(sum));
15         for(int i = 1; i <= m; i++) {
16             scanf("%d%d", &ma[i].first, &ma[i].second);
17         }
18         for(int i = 1; i <= n; i++) {
19             scanf("%d%d", &ta[i].first, &ta[i].second);
20         }
21         sort(ma + 1, ma + m + 1);
22         sort(ta + 1, ta + n + 1);
23         int j = m;
24         long long ans = 0, a = 0;
25         for(int i = n; i >= 1; i--) {
26             while(j && ma[j].first >= ta[i].first) {
27                 sum[ma[j].second]++;
28                 j--;
29             }
30             int temp = ta[i].second;
31             while(temp < F && !sum[temp]) {
32                 temp++;
33             }
34             if(temp == F) continue;
35             sum[temp]--;
36             ans += 500 * ta[i].first + 2 * ta[i].second;
37             a++;
38         }
39         printf("%lld %lld\n", a, ans);
40     }
41 
42     return 0;
43 }
AC代码

 

posted @ 2018-05-15 17:50  garage  阅读(88)  评论(0编辑  收藏  举报