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 }