【2017泉州基地校集训】最优排名[贪心]

My Solution

我们定义“干掉”一个人的花费为他的空间减去他的分数再加一(易得)。

由题可知,我们可以把除自己之外的选手分为“气球多于自己”和“气球少于自己”的两组。每次把自己的气球送给“气球多于自己”的中“花费最小的”,把他从这一组中去掉(干掉),再把一些选手从“气球少于自己”的一组移到“气球多于自己”的一组,更新自己当前的排名。

以上过程相当于一次模拟,自己的气球数和排名都得到了更新,不断进行这样的模拟,直到自己的气球数不足以干掉“气球多于自己”的任何一名选手为止,取这一过程中排名的最小值即为最终的答案(事实证明这种贪心策略是正确的)。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
#define inf 0x3f3f3f3f

typedef long long ll;

ll read(){
    char ch;
    ll re=0;
    bool flag=0;
    while((ch=getchar())!=‘-‘&&(ch<‘0‘||ch>‘9‘));
    ch==‘-‘?flag=1:re=ch-‘0‘;
    while((ch=getchar())>=‘0‘&&ch<=‘9‘)  re=re*10+ch-‘0‘;
    return flag?-re:re;
}

struct node{
    ll w,c;
    node(ll w=0,ll c=0):
        w(w),c(c){}
};

const int maxn=300005;

int n,ans=0,ens,cnt=0;
ll w1;
vector<node> a;
node b[maxn],temp;

//大根堆的排序与普通排序相反
inline bool cmp1(const node &n1,const node &n2){
    return n1.c>n2.c;
} 

inline bool cmp2(const node &n1,const node &n2){
    return n1.w>n2.w;
}

void init(){
    n=read()-1;  w1=read();
    ll w,tmp=read();
    for(int i=1;i<=n;i++){
        w=read();  tmp=read();
        //初始排名在小A之前
        if(w>w1){
            a.push_back(node(w,tmp-w+1));
            ++ans;
        }
        else{
            b[++cnt]=node(w,tmp-w+1);
        }
    }
    ens=++ans;
}

void solve(){
    make_heap(a.begin(),a.end(),cmp1);
    sort(b+1,b+cnt+1,cmp2);
    //在b中的指针
    int g=1;
    //ens==1时自然是最优解?
    while(w1>0&&ens>1){
        //当前的气球不够
        if(w1<a[0].c)  break;
        //模拟
        w1-=a[0].c;
        //处理完了,把a[0]放到队尾,去掉队尾
        pop_heap(a.begin(),a.end(),cmp1);  a.pop_back();
        ens--;
        while(g<=cnt&&b[g].w>w1){
            a.push_back(b[g]);
            //对新放入a的元素进行一次堆排(应该放到队首?)
            push_heap(a.begin(),a.end(),cmp1);
            g++;
            ens++;
        }
        //更新答案
        ans=min(ans,ens);
    }
    printf("%d\n",ans);
}

int main(){
    //freopen("rank.in","r",stdin);
    //freopen("rank.out","w",stdout);

    init();
    solve();

    return 0;
}
时间: 2024-10-14 04:27:35

【2017泉州基地校集训】最优排名[贪心]的相关文章

hdu5289||2015多校联合第一场1002贪心+RMQ

http://acm.hdu.edu.cn/showproblem.php?pid=5289 Problem Description Tom owns a company and he is the boss. There are n staffs which are numbered from 1 to n in this company, and every staff has a ability. Now, Tom is going to assign a special task to

2017清北学堂集训笔记——动态规划Part2

啊~到下午啦,我们进入Part2!--一个简洁的开头 我们来探讨第一类问题--路径行走问题 经典例题:方格取数(Luogu 1004) 设有 N*N 的方格图 (N<=9),我们将其中的某些方格中填入正整数,而其他的方格中则放入数字 0.* 某人从图的左上角的 A 点出发,可以向下行走,也可以向右走,直到到达右下角的 B 点.在走过的路上,他可以取走方格中的数(取走后的方格中将变为数字 0).* 此人从 A 点到 B 点共走两次,试找出 2 条这样的路径,使得取得的数之和为最大.- 与数字金字塔

2017 全国多校第十场 训练日志

solve 2(310 / 634) J题题意搞错一口大锅. dzcH题结论猜对了,只是树上二分图不用匈牙利算法,能换成更高效的写法. B Array Challenge 高斯消元 + 矩阵快速幂 H Monkeys 二分图结论 J Schedule 优先队列 <qj> 题意: 有n个任务,给你开始时间和结束时间,有无数台机器,每台机器可以在同一时间最多处理一个任务,并且开机之后,只能关一次机,不能中途关机又开机. 问至少需要多少机器,在这么多台机器的情况下,最少花费多少.(花费 = 每台机器

2017清北学堂集训笔记——图论

我们进入一个新的模块——图论! emmmmm这个专题更出来可能有点慢别介意,原因是要划的图和要给代码加的注释比较多,更重要的就是...这几个晚上我在追剧!!我们的少年时代超级超级超级好看,剧情很燃啊!!咳咳,好吧下面回归正题. 一.图的存储: 1.邻接矩阵: 假设有n个节点,建立一个n×n的矩阵,第i号节点能到达第j号节点就将[i][j]标记为1(有权值标记为权值), 样例如下图: 1 /*无向图,无权值*/ 2 int a[MAXN][MAXN];//邻接矩阵 3 int x,y;//两座城市

loj6102 「2017 山东二轮集训 Day1」第三题

传送门:https://loj.ac/problem/6102 [题解] 贴一份zyz在知乎的回答吧 https://www.zhihu.com/question/61218881 其实是经典问题 # include <stdio.h> # include <string.h> # include <iostream> # include <algorithm> using namespace std; typedef long long ll; typed

2017浙江工业大学-校赛决赛 竹之书

Description 由于某些原因菲莉丝拿到了贤者之石,所以好像变得很厉害了好像变得很厉害的菲莉丝想要炼成幻想乡,其中有一个原料是稗田一族对幻想乡历史的记录.现在菲莉丝拿到了一个被某只魔粘性精神体加密过的的卷轴.密文通过原文和一个正整数key加密形成,而key和密文又有一定关联.现给出密文,求key值 已知密文s和key值关系如下已知密文s是一串正整数s1,s2,s3--sn,A为s中所有元素的和,B为s中所有元素的积,key为B mod A 数据范围si,A在(0,1e17]范围内0<n<

2017浙江工业大学-校赛决赛 XiaoWei的战斗力

Description XiaoWei沉迷RPG无法自拔,但是他的战斗力只有5,所以他决定氪金提升战斗力.XiaoWei购买了n个福袋.打开1个福袋后,有以下三种情况出现:1.获得屠龙宝刀,概率为p1:2.获得火麒麟,概率为p2:3.什么都没获得,概率为1-p1-p2:已知每把屠龙宝刀能够使战斗力*2,每把火麒麟能够使战斗力*1.5.XiaoWei虽然初始战斗力很弱,但是潜力无限,可以装备任意数量的屠龙宝刀和火麒麟,并且效果可以叠加.XiaoWei想知道,打开n个福袋后并装备武器后,他的战斗力期

2017浙江工业大学-校赛决赛 小马哥和数列

Description 小马哥是个追求完美的人,现在给定一个正整数数列,和正整数p,设这个数列中的最大值是M,最小值是m,如果M <= m * p,则称这个数列是完美的,现在给定参数p和一些正整数,请你从中选择尽可能多的数构成一个完美数列. Input 多组数据.输入第一行给出两个正整数N和p,其中N(<= 10^5)是输入的正整数的个数,p(<= 10^9)是给定的参数.第二行给出N个正整数,每个数不超过10^9. Output 在一行中输出最多可以选择多少个数可以用它们组成一个完美数

2017浙江工业大学-校赛决赛 猜猜谁是我

Description 女神YSJ给Martin发了一个视频."猜猜里面哪个是我." 女神说.作为一个脸盲,再加上多年不见,Martin已经完全不知道女神长成了什么样子,他表示完全认不出来.好在Martin手上还有一张YSJ小时候的照片,他可以拿照片和视频里的人进行特征比对,从而找出女神.为了简化问题,我们将YSJ小时候的脸表示成一个800行800列的矩阵,然后给出眼睛.鼻子.嘴巴的中心在脸上的坐标,全部用整数表示.视频中的其他人也都按照这个方式表示,截取正脸并且缩放到800x800以