一个贪心贪不清楚的题目

Mr.Maxwell and attractions E起来编程暨第三届湖北省赛

B-Mr.Maxwell and attractions_“深圳计算科研院杯“E起来编程暨第三届湖北省赛 (nowcoder.com)

题意

有n个户外,m个户内活动,总共T天,至少K下午天去户外

第二次去同一个地点获得开心值为原本的0.6, 如果同时满足户外和下午,则开心值为原来0.6倍的基础上在乘0.8

问:开心值最大值为多少?

题解

贪心策略:室内的尽量放下午,室外的尽量放上午

但是当只能安排在下午了,要比较的是户内最大值 和 户外最大值*0.8

if(mor == 0) {flag = a >= 0.8 * b ? 1 : 0;}
else {flag = a >=  b ? 1 : 0;}

ps: 队友用的是优先队列,因为有效值为队头

我更喜欢multiset(顺手,而且multiset可以在中间取值,删值

but,multiset常数大,慢的很!

//看看下面,是队列时间的三倍

在这里插入图片描述

#include <bits/stdc++.h>
const int MAX = 1e5 + 10;
using namespace std;
typedef long long ll;
const int INF = 1e9 + 7;

struct node {
    double a;
    bool operator<(const node &x) const {
        return a > x.a;
    }
};

multiset<node> ans1, ans2;
double indo[MAX], outdo[MAX];

int main() {
    int N, M, T, K;
    scanf("%d%d%d%d", &N, &M, &T, &K);
    for (int i = 0; i < N; i++) {
        scanf("%lf", &indo[i]);
        ans1.insert({indo[i]});
    }
    for (int i = 0; i < M; i++) {
        scanf("%lf", &outdo[i]);
        ans2.insert({outdo[i]});
    }
    double res = 0;
    int mor = T - K;
    int aft = K;
    while (1) {
        if (!mor && !aft) break;
        double a = ans1.begin()->a;
        double b = ans2.begin()->a;

        //室内的尽量放下午,室外的尽量放上午
        bool flag;
        if(mor == 0) {flag = a >= 0.8 * b ? 1 : 0;}
        else {flag = a >=  b ? 1 : 0;}
        if(flag) {
            res += a;
            ans1.erase(ans1.begin());
            ans1.insert({a * 0.6});
            if(aft >= 1) {
                aft--;
            }
            else if(mor >= 1){
                mor--;
            }
            else break;
        }
        else {
            if(mor >= 1) {
                mor--;
                res += b;
                ans2.erase(ans2.begin());
                ans2.insert({b * 0.6});
            }
            else {
                aft--;
                res += b * 0.8;
                ans2.erase(ans2.begin());
                ans2.insert({b * 0.6});
            }
        }
    }
    printf("%.2lf\n", res);
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值