hdu 4864 Task

  题目链接:hdu 4864

  其实就是个贪心,只是当初我想的有偏差,贪心的思路不对,应该是这样子的:

  因为 xi 的权值更重,所以优先按照 x 来排序,而这样的排序方式决定了在满足任务(即 xi >= xj && yi >= yj)的所有机器中(设为 S)优先选择更贴近 yj 的 yi(因为我们肯定是选择最贴近任务 x,y 值的机器,要么是 xi 最贴近,要么是 yi 最贴近),这样子可以使得浪费最小——因为在后续的任务中,xj 只会越来越小,S 中的任何一台机器的 xi 值都能满足要求,但 yj 就不一定了,因为一开始是按照 x 来排序的,所以 yj 有可能会比之前的更大,因此我们为当前任务选择机器时 yi 能小则小,把 yi 更大的机器留给后续有可能满足的任务,这样子就可以使得当前的浪费最小。

  用个数组来作标记,整个程序就是近乎 O(n) 的复杂度了:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 typedef long long ll;
 6 const int N = 100005;
 7 
 8 struct node {
 9     int x,y;
10     node() {}
11     node(int x, int y): x(x), y(y) {}
12     bool operator < (const node &n2) const {
13         if(x == n2.x)   return y > n2.y;
14         return x > n2.x;
15     }
16     void read()  {   scanf("%d %d",&x,&y);   }
17 } mach[N], task[N];
18 
19 int c[102];
20 
21 int main() {
22     int n,m;
23     while(~scanf("%d %d",&n,&m)) {
24         for(int i = 0; i < n; ++i)
25             mach[i].read();
26         for(int i = 0; i < m; ++i)
27             task[i].read();
28         sort(mach, mach + n);
29         sort(task, task + m);
30         memset(c, 0, sizeof c);
31         int num = 0;
32         ll ans = 0;
33         for(int i = 0, j = 0; j < m; ++j) {
34             while(i < n && mach[i].x >= task[j].x) {
35                 c[mach[i].y]++;
36                 ++i;
37             }
38             for(int k = task[j].y; k <= 100; ++k) {
39                 if(c[k]) {
40                     ++num;
41                     ans += 500 * task[j].x + 2 * task[j].y;
42                     --c[k];
43                     break;
44                 }
45             }
46         }
47         printf("%d %I64d\n",num,ans);
48     }
49     return 0;
50 }
View Code
posted @ 2015-10-13 12:06  Newdawn_ALM  阅读(140)  评论(0编辑  收藏  举报