YbtOJ「基础算法」第2章 贪心算法

YbtOJ大全

【例题1】奶牛晒衣服

一道很基础的贪心,用大根堆维护当前状态下衣服湿度的最大值,然后让它减去 b b b,同时维护一个时间戳 t t t,判断 q . t o p ( ) − t × a > 0 q.top() - t \times a > 0 q.top()t×a>0 是否成立即可。

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#define re register
#define rep(a,b,c)  for(re int a(b) ; a<=c ; ++a)
#define drep(a,b,c) for(re int a(b) ; a>=c ; --a)
using namespace std;
inline int read(){
   
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){
   if(ch == '-') f=-1 ; ch=getchar();}
    while(ch>='0'&&ch<='9'){
   x=(x<<1)+(x<<3)+(ch^48) ; ch=getchar();}
    return x*f;
}
priority_queue<int> q;
const int M = 5e5 + 10;
int n,a,b,x,t;
signed main(){
   
    n = read(),a = read(),b = read();
    rep(i,1,n) x = read(),q.push(x);
    while(q.top() - t*a > 0){
   
        int u = q.top();
        q.pop();
        u -= b;
        q.push(u);
        t++;
    }
    printf("%d\n",t);
    return 0;
}

【例题2】雷达装置

一开始的思路是按左端点从小到大排序,然后记录下来当前的最大位置 p o s pos pos,每进入一个 a [ i ] . r a[i].r a[i].r 就和 p o s pos pos 比较,如果小就不管,大就更新。但如果有重叠的部分,只记录右端点,如果有两个小段,一个在中间,一个跨过了右端点,会让答案变小。

正确的贪心是按右端点升序排序,同样记录右端点 p o s pos pos,如果当前进入的 a [ i ] . l a[i].l a[i].l a [ i ] . r a[i].r a[i].r 的区间包含 p o s pos pos,可以不管,否则记录能到的最大右端点。

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#define re register
#define rep(a,b,c)  for(re int a(b) ; a<=c ; ++a)
#define drep(a,b,c) for(re int a(b) ; a>=c ; --a)
using namespace std;
inline int read(){
   
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){
   if(ch == '-') f=-1 ; ch=getchar();}
    while(ch>='0'&&ch<='9'){
   x=(x<<1)+(x<<3)+(ch^48) ; ch=getchar();}
    return x*f;
}
const int M = 1e5+10;
int n;
double d;
struct node{
   
    double l,r;
    friend bool operator < (node a,node b) {
    return a.r < b.r; }
}a[M];
signed main(){
   
    n = read();
    scanf("%lf",&d);
    rep(i,1,n){
   
        double x,y;
        scanf("%lf%lf",&x,&y);
        if(y > d) {
    printf("-1\n"); return 0; }
        a[i].l = 1.0 * (1.0 * x - 1.0 * sqrt(d*d - y*y));
        a[i].r = 1.0 * (1.0 * x + 1.0 * sqrt(d*d - y*y));
    }
    sort(a+1,a+n+1);
    int ans = 1;
    double you = a[1].r;
    rep(i,2,n){
   
        if(a[i].l <= you && you <= a[i].r) continue;
        ans++;
        you = a[i].r;
    }
    printf("%d\n",ans);
    return 0;
}

【例题3】畜栏预定

需要维护一个小根堆,存当前牛所在牛栏的编号和时间的右端点。每一次进来一头牛,把它的左端点和 q . t o p ( ) . r q.top().r q.top().r 比较

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值