• Moo University


    poj2010:http://poj.org/problem?id=2010

    题意:给你c个点,每个点有两个属性,一个是成为成绩g,一个是资金f,又给你总资金F,然后让你从这c个点中选出n个,这n个点满足两点:1,n个点的资金和不大于总资金F,2:n个点成绩的中位数尽可能的大。
    题解:这一题开始自己也没有什么思路,看了别人的思路发现那样的做法好巧妙啊。
    思路:首先按照成绩给c个点进行排序,然后对于每个i,计算出在i之前选出n/2个点,然后在i之后选出n/2个点,然后枚举每个i,选出最大的成绩。对于i之前的,只要选出n/2个点且资金之和最小的点即可,如果连最小的资金之和都满足不了资金和不大于F,则其他情况都不会满足。另外:对于选出资金和最小的n/2个。可以用最大堆或者优先队列来实现,每次加入堆中,只保留当前最小的n/2即可!

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<algorithm>
     5 #include<queue>
     6 using namespace std;
     7 struct Node{
     8    long long g;
     9   long long f;
    10 }node[100002];
    11 int cmp(Node a,Node b){
    12   return a.g<b.g;
    13 }
    14 long long n,c;
    15 long long aa[100002],bb[100002];//分别记录在i之前选出n/2个点最小的资金和和之后的。
    16 long long f;
    17 int main(){
    18   while(~scanf("%I64d%I64d%I64d",&n,&c,&f)){
    19      long long sum=0;
    20   for(int i=1;i<=c;i++)
    21   scanf("%I64d%I64d",&node[i].g,&node[i].f);
    22     sort(node+1,node+c+1,cmp);
    23       priority_queue<long long>Q;int counts=0;
    24         for(int i=1;i<c-n/2;i++){
    25          sum+=node[i].f;
    26          Q.push(node[i].f);
    27          counts++;
    28          if(i>=n/2){
    29               if(counts>n/2){
    30                long long tmp=Q.top();
    31                 Q.pop();
    32                 sum-=tmp;
    33               }
    34                aa[i+1]=sum;
    35          }
    36     }
    37       sum=0;counts=0;int counts2=0;
    38      priority_queue<long long>Q2;
    39       for(int i=c;i>n/2+1;i--){
    40          sum+=node[i].f;
    41          Q2.push(node[i].f);
    42            counts++;
    43            counts2++;
    44          if(counts>=n/2){
    45             if(counts2>n/2){
    46           long long tmp=Q2.top();
    47              Q2.pop();
    48             sum-=tmp;
    49             }
    50             bb[i-1]=sum;
    51          }
    52     }
    53 long long anss=0;bool flag=false;
    54     for(int i=c-n/2;i>n/2;i--){
    55         if(bb[i]+aa[i]+node[i].f<=f){
    56             flag=true;
    57             anss=node[i].g;
    58             break;
    59         }
    60     }
    61     if(flag)printf("%I64d
    ",anss);
    62     else printf("-1
    ");
    63   }
    64 
    65 }
    View Code
  • 相关阅读:
    线上一次大量 CLOSE_WAIT 复盘
    etcd 性能优化实践
    Web 前端密码加密是否有意义?
    tmp
    京东 PC 首页 2019 改版前端总结 原创: 何Jason,EC,小屁 凹凸实验室 今天
    http://stblog.baidu-tech.com/?p=1684) coredump调试记录
    Java字节码增强探秘
    dedecms 织梦更改rss的路径、网站地图sitemap的路径
    dedecms时间日期标签大全
    织梦CMS被挂马特征汇总
  • 原文地址:https://www.cnblogs.com/chujian123/p/3536185.html
Copyright © 2020-2023  润新知