• nowcoder-第三届湖北省赛-Mr.Maxwell and attractions (贪心)


    在这里插入图片描述
    在这里插入图片描述

    一道比较细节的贪心题
    题意:
    一个人可以选择在上午上班或者是在下午上班,不上班的时间可以摸鱼游玩
    有n个室内的风景,m个室外的风景,这n+m个风景有一个漂亮值
    对于这n+m个风景,如果第一次观看漂亮值转换为开心值比率为100%,如果重复观看,每重复一次就会变成之前的60%
    对于室外的风景,下午观看会降到80%,上午观看不影响,如果在下午重复观看室外的风景,获得的开心值就是preVal * 80% * 60 %。(效果加成作用)

    问这个人至少在白天工作k天( >= k),总共n天,最大能获得多少开心值

    输入:

    2 1 4 2
    4 3
    7
    

    输出:

    18.20
    

    样例解释:
    上午7上午7*0.6下午4下午3
    7 + 7 * 0.6 + 4 + 3 == 18.20

    很容易想到用优先队列维护两块(室内室外)的风景,每当观看过之后,就对这个值*0.6,因为已经观看过了
    然后要在白天工作至少k天,所以也就意味着至少要在下午观赏k天

    先来一份Wa的赛事代码,队友实现的非常OK,但是在我们讨论过程中还是细节没有考虑好

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 100010;
    priority_queue<double,vector<double>,less<double> >q1;//室内
    priority_queue<double,vector<double>,less<double> >q2;//室外
    int main()
    {
        int n,m,k,t; cin >> n >> m >> t >> k;
        for(int i=1;i<=n;i++)
        {
            double x; cin >> x;
            q1.push(x);
        }
        for(int i = 1;i <= m;i++)
        {
            double x; cin >> x;
            q2.push(x);
        }
        k = t - k;
        double ans = 0;
        for(int i = 1;i <= k;i++)
        {
            double x = q1.top();q1.pop();
            double y = q2.top();q2.pop();
            if(x >= y)
            {
                ans += x;
                x *= 0.6;
            }
            else{
                ans += y;
                y *= 0.6;
            }
             q1.push(x);
             q2.push(y);
        }
        k = t - k;
        for(int i = 1;i <= n;i++)
        {
             double x = q1.top();q1.pop();
             double y = q2.top();q2.pop();
             if(x >= y * 0.8){
                 ans += x;
                 x *= 0.6;
             }
            else{
                ans += y * 0.8;
                y *= 0.6;
            }
            q1.push(x);
            q2.push(y);
        }
        printf("%.2lf",ans);
        return 0;
    }
    

    这份代码错就错在,将两部分进行分开考虑,实际上是不应该进行分开考虑的

    也就是说:
    在这里插入图片描述
    所以最终Code就很容易啦:

    int n,m,t,k;
    priority_queue<double> quea,queb;
    int main() {
    	cin >> n >> m >> t >> k;
    	for(int i=1; i<=n; i++) {
    		double t; cin >> t;
    		quea.push(t);
    	}
    	for(int i=1; i<=m; i++) {
    		double t; cin >> t;
    		queb.push(t);
    	}
    	double ans = 0;
    	k = t-k;
    	for(int i=1;i<=t;i++){
    		double topa = quea.top();
    		double topb = queb.top();
    		double mul = 1.0;
    		if(k <= 0) mul = 0.8;///afternoon 
    		if(topa > topb * mul){
    			ans += topa;
    			quea.pop();quea.push(topa * 0.6);
    		}else{
    			ans += topb * mul;
    			queb.pop();queb.push(topb * 0.6);
    			k --;
    		}
    	}
    	printf("%.2lf
    ",ans);
    	return 0;
    }//ac_code
    
  • 相关阅读:
    codevs2606 约数和问题
    UOJ150 运输计划
    codevs1279 Guard 的无聊
    codevs1997 守卫者的挑战
    codevs1291 火车线路
    codevs1217 借教室
    codevs1281 Xn数列
    codevs1218 疫情控制
    codevs1199 开车旅行
    BZOJ1941 [Sdoi2010]Hide and Seek
  • 原文地址:https://www.cnblogs.com/PushyTao/p/15101057.html
Copyright © 2020-2023  润新知