zoukankan      html  css  js  c++  java
  • hdu4864 hdu4268 贪心 lower_bound

    hdu4864

    题意:

    有n个机器,m个任务,n,m<=100000,每个机器都有工作时间的最大限制xi(0<xi<1440)和完成的最大难度yi(0<=yi<=100),每个任务也有所需要的时间和难度,只要机器的时间大于等于任务,难度大于等于任务,该任务就可以被机器完成,每完成一个任务就可以得到500*xi+2*yi的money,问最多能有多少个任务被完成,并且保证完成任务数量最多的情况下,所得到的money最多是多少?

    思路:

    由于money是500*x+2*y,而y最大是100,则只要保证任务的x最大,那么得到的钱一定是最多的。

    将任务按照时间x从大到小排序,然后依次用任务查找机器,时间x从大到小保证了得到的钱是最多的,然后每个任务找出大于该任务难度y且与难度y最接近的机器完成该任务。现在有个问题需要证明一下,每次找难度最接近的机器,那么时间x只是大于任务x即可,时间是否物尽其用了呢?是否有浪费呢?不会,因为任务的x是从大到小排序遍历,如果任务找到了一个大于自身时间x的机器,就用,即使有别的x更大的机器没有被用,但是可以留下来给别的任务用。

    比赛的时候代码WA,虽然也是贪心,但是用的机器查找任务,导致x做到了物尽其用,y并没有做到,so WA~

    不要迷迷糊糊的写,要严谨的证明全对再下手写~

     1 /*===============================================================
     2 *   Copyright (C) 2014 All rights reserved.
     3 *   
     4 *   File&#160;Name:&#160;hdu4864.cpp
     5 *   Author:sunshine
     6 *   Created&#160;Time:&#160;2014年07月23日
     7 *
     8 ================================================================*/
     9 #include <map>
    10 #include <set>
    11 #include <queue>
    12 #include <stack>
    13 #include <math.h>
    14 #include <stdio.h>
    15 #include <string.h>
    16 #include <iostream>
    17 #include <algorithm>
    18 
    19 using namespace std;
    20 
    21 #define N 100005
    22 
    23 struct node{
    24     int x,y;
    25     bool operator < (const node &n1) const{
    26         if(x != n1.x) return x > n1.x;
    27         return y > n1.y;
    28     }
    29 }task[N];
    30 
    31 int main(){
    32     int n,m;
    33     int x,y;
    34     while(cin >> n >> m){
    35 
    36         multiset<int> S[105];
    37         long long res = 0;
    38         int cnt = 0;
    39 
    40         for(int i = 0;i < n;i ++){
    41             scanf("%d%d", &x, &y);
    42             S[y].insert(x);
    43         }
    44 
    45         for(int i = 0;i < m;i ++){
    46             scanf("%d%d", &task[i].x, &task[i].y);
    47         }
    48 
    49         sort(task,task+m);
    50 
    51         for(int i = 0;i < m ;i ++){
    52             x = task[i].x;
    53             y = task[i].y;
    54 
    55             for(int j = y;j <= 100;j ++){
    56                 if(S[j].empty()) {
    57                     continue;
    58                 }
    59 
    60                 multiset<int>::iterator it = S[j].lower_bound(x);
    61 
    62                 if(it == S[j].end() || *it < x){
    63                     continue;
    64                 }else{
    65                     cnt ++;
    66                     res += 500 * x + 2 * y;
    67                     S[j].erase(it);
    68                     break;
    69                 }
    70             }
    71         }
    72         printf("%d %I64d
    ",cnt,res);
    73     }
    74     return 0;
    75 }
    View Code

    hdu4268

    题意:

    Alice有n个纸片,Bob有n个纸片,n<=100000每个纸片有长度和宽度,已知这2*n个纸片的长和宽,求Alice最多能覆盖Bob多少张纸片,每张纸片只能被用一次。

    思路:

    将这2*n张纸片按照长x从大到小排序,y从大到小排序,如果x、y相等,则Alice的纸片排在前面,用Bob去查找Alice,即Alice所有的纸片插入到set中,但是并不是一下子全部插入到set中,而是边插入set处理边求解Bob的第i张纸片能否被覆盖,这样能够保证之前插入的所有纸片的长x都大于等于自身的x,每次遇到Alice的纸片则插入到set中,每次遇到Bob的纸片则在set中查找刚好大于等于y的第一个Alice的纸片,然后把它删除,依次。

     1 /*===============================================================
     2 *   Copyright (C) 2014 All rights reserved.
     3 *   
     4 *   File&#160;Name:&#160;hdu4268.cpp
     5 *   Author:sunshine
     6 *   Created&#160;Time:&#160;2014年07月23日
     7 *
     8 ================================================================*/
     9 #include <map>
    10 #include <set>
    11 #include <queue>
    12 #include <stack>
    13 #include <math.h>
    14 #include <stdio.h>
    15 #include <string.h>
    16 #include <iostream>
    17 #include <algorithm>
    18 
    19 using namespace std;
    20 
    21 #define N 100010
    22 
    23 struct node{
    24     int x,y;
    25     bool id;
    26 }p[2*N];
    27 
    28 int cmp(node n1,node n2){
    29     if(n1.x == n2.x && n2.y == n2.y) return n1.id > n2.id;
    30     if(n1.x != n2.x) return n1.x > n2.x;
    31     return n1.y > n2.y;
    32 }
    33 
    34 int main(){
    35     int cas;
    36     int n;
    37     int x,y;
    38     scanf("%d", &cas);
    39     while(cas --){
    40         scanf("%d", &n);
    41         for(int i = 0;i < n;i ++){
    42             scanf("%d%d", &p[i].x, &p[i].y);
    43             p[i].id = 1;
    44         }
    45 
    46         for(int i = n;i < 2 * n;i ++){
    47             scanf("%d%d", &p[i].x, &p[i].y);
    48             p[i].id = 0;
    49         }
    50 
    51         sort(p,p + 2 * n,cmp);
    52         multiset<int>S;
    53         int cnt = 0;
    54         for(int i = 0;i < 2 * n;i ++){
    55             if(p[i].id){
    56                 S.insert(p[i].y);
    57             }else{
    58                 y = p[i].y;
    59                 multiset<int>::iterator it = S.lower_bound(y);
    60 
    61                 if(it == S.end() || *it < y){
    62                     continue;
    63                 }else{
    64                     S.erase(it);
    65                     cnt ++;
    66                 }
    67             }
    68         }
    69         printf("%d
    ",cnt);
    70     }
    71     return 0;
    72 }
    View Code
  • 相关阅读:
    Inno Setup命令行安装卸载参数
    Fragment生命周期
    ubuntu 64位系统下加速Android模拟器
    Java中对SQLite数据库操作 操作db文件
    系统权限管理设计
    java 中的序列化是什么意思?有什么好处?
    js实现定时调用的函数setInterval()
    tomcat 并发配置优化
    centOS下 JDK的三种安装方式
    Linux 配置静态Ip地址
  • 原文地址:https://www.cnblogs.com/-sunshine/p/3862810.html
Copyright © 2011-2022 走看看