1671.扑克牌

信息学奥赛一本通 贪心算法

【题目描述】


一副扑克牌有n张普通牌加一张特殊牌
现在n种牌各有a1 , a2 , … , an张,还有 b bb 张特殊牌
一副牌可以由n种普通牌各一张组成,也可以由n−1种普通牌各一张再加一张特殊牌组成
输出最多能整理出的牌的副数。

【输入】


第一行给出n和b。
第二行给出a1,a2,…,an。

【输出】


输出最多能整理出的牌的副数。

【数据】


对于20%的数据,1≤n≤100,牌的数量小于100。
对于40%的数据,1≤n≤3000。
对于100%的数据,1≤n≤1000000,牌的数量 ≤10^{6}
时间限制: 1000ms
内存限制: 262144KB

【输入样例】

5 5
5 5 5 5 5

【输出样例】

6

【分析】

题目描述不是太好理解,现在对样例数据进行一个解读。5种牌分别各有5张,就以1、2、3、4、5来表示,即1有5张,2有5张……那么答案的6副牌是什么样的呢,我用表格来表示,每一行表示一副牌,其中T表示特殊牌。

T2345
1T345
12T45
123T5
1234T
12345

补充一个样例:

5 5

5 1 2 3 4

答案:3

也是五种牌,每种牌的数量不相同了,需要先对牌的数量进行一个排序,表格中上面三行对应答案的3副牌。

T2345
T2345
1T345
45
5

题目适用于贪心来解题,调整几种牌中数量最小的那个。补充样例中,不使用特殊牌,只能凑出1副牌(1,2,3,4,5),将特殊牌补充到1里,可以凑出2副牌(T,2,3,4,5 / 1,2,3,4,5),再将特殊牌补充到1、2各一个,可以凑出3副牌,如上面表格所示。那么可以继续添加特殊牌吗?再添加一个T到1、2、3中一列,还有两个空无法填充,即用了4个特殊牌也只能凑出3副牌。

补充特殊牌退出条件有两个:

1、使用特殊牌的数量大于能凑出的牌数,即大于队列中最小的那个数,如补充例子里展示的那样

2、特殊牌用完了

#include<bits/stdc++.h>
using namespace std;
int n,b;
//优先队列
priority_queue <int, vector<int>,greater<int>> q;
int ans;
int main() {
    cin>>n>>b;
    for(int i=1;i<=n;i++){//优先队列保存n张牌
        int a;
        cin>>a;
        q.push(a);
    }
    ans=q.top();//记录最初可以凑出的牌数
    for(int i=1;i<=b;i++){//将特殊牌补充到队列里
        int t = q.top();
        q.pop();
        t++;//加到最少的那种牌里
        q.push(t);//补充后放回队列
        ans=q.top();//当前最少的牌数,即当前可凑出的牌数
        if (i>ans){//如果使用的特殊牌超过了整副牌数量,表示无法再凑出更多的牌数了
            break;
        }
    }
    cout<<ans;//输出答案
    //cout << q.top()
    return 0;
}

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值