[CQOI2010]扑克牌

[CQOI2010]扑克牌

https://ac.nowcoder.com/acm/problem/19916

二分

题意:
你有n种牌,第i种牌的数目为ci。另外有一种特殊的牌:joker,它的数目是m。你可以用每种牌各一张来组成一套牌,也可以用一张joker和除了某一种牌以外的其他牌各一张组成1套牌。比如,当n=3时,一共有4种合法的套牌:{1,2,3}, {J,2,3}, {1,J,3}, {1,2,J}。 给出n, m和ci,你的任务是组成尽量多的套牌。每张牌最多只能用在一副套牌里(可以有牌不使用)。

我不知道贪心行不行,如果有大佬知道怎么贪心,希望指点一下。

下面是二分做法:
我们想对结果进行二分,我们可以组成的套数一定是在[0,1e9) 左闭右开,我们在这个范围内进行二分搜索。
对于左端点l,右端点r,中间点mid,
如果中间点为true,即我们可以凑出mid及mid以上的套装数,那么我们让l = mid+1
否则我们让 r = mid-1
这样最后答案一定为l-1

关键是如何判断我们是否可以凑出mid或mid以上的套装数

我们想想,如果我们要凑出mid套卡组,对于卡牌a[i],a[i]<mid。
那么我们肯定要用joker代替他!如果最后我们,需要使用的joker数大于我们实际拥有的joker数
那么我们肯定不能成功凑出mid套卡组。
除此之外还有什么限定条件呢?对了,对于一套卡组我们最多只能用joker替代其中的一张,及我们
不能出现[j,j,3]的情况。那么这个限制条件如何体现呢?
我们想象假设mid = 6;a[i]=4,那么我们要使用2张joker代替他 a[j] = 3我们使用三张joker代替他。
我们这样代替吗?1代表一张卡牌
ai [ j, j, 1, 1, 1, 1]
aj [ j, j, j, 1, 1, 1]
不会的,因为这样当我们从上方去拿第一套卡组时,就有大于一张的joker了
所以我们这样放
ai [ j, j, 1, 1, 1, 1]
aj [ 1, 1, j, j, j, 1]
有没有看出什么,我们只能接着上一次的末尾放置joker
最多放置mid张joker
所以倘若我们放置的joker数大于mid的话,也依然是false

代码如下,注意细节

#include<iostream>;
#include<algorithm>;
using namespace std;
typedef long long ll;
const int max_r = 1e9 + 10;
const int max_n = 55;
int a[max_n];
int n, k;

int solve() {
    int l = 0;int r = max_r;
    while (l <= r) {
        int mid = (r + l) >> 1;
        ll cnt = 0;
        for (int i = 1;i <= n;i++)
            if (a[i] < mid)
                cnt += mid - a[i];
        if (cnt > mid || cnt > k) r = mid - 1;
        else l = mid + 1;
    }return l - 1;
}

int main() {
    ios::sync_with_stdio(0);
    cin >> n >> k;
    for (int i = 1;i <= n;i++)cin >> a[i];
    cout << solve() << endl;
}
全部评论
请问你知道二分法的时候什么时候用l
1 回复 分享
发布于 2020-05-31 15:21
就是细节怎么写包括while是》还是》=;;mid除以2前要不要+1;;最后l=mid还是mid+1;;输出l-1还是l还是r或者r+1
点赞 回复 分享
发布于 2020-06-01 18:55
emmmm,乱码了。。。
点赞 回复 分享
发布于 2020-06-01 18:54
就是二分写代码,是while(l<r>>1 or mid=(l+r+1)>>1;;l=mid+1 or l=mid;;r=mid-1 or r=mid;;cout<<l cout="" or=""><<l-1 cout="" or=""><<r cout="" or=""><</r></l-1></l></r>
点赞 回复 分享
发布于 2020-06-01 18:53

相关推荐

06-27 12:54
已编辑
门头沟学院 Java
累了,讲讲我的大学经历吧,目前在家待业。我是一个二本院校软件工程专业。最开始选专业是觉得计算机感兴趣,所以选择了他。本人学习计算机是从大二暑假结束开始的,也就是大三开始。当时每天学习,我个人认为Java以及是我生活的一部分了,就这样持续学习了一年半,来到了大四上学期末,大概是在12月中旬,我终于找的到了一家上海中厂的实习,但我发现实习生的工作很枯燥,公司分配的活也不多,大多时间也是自己在自学。就这样我秋招末才找到实习。时间来到了3月中旬,公司说我可以转正,但是转正工资只有7000,不过很稳定,不加班,双休,因为要回学校参加答辩了,同时当时也是心高气傲,认为可以找到更好的,所以放弃了转正机会,回学校准备论文。准备论文期间就也没有投递简历。然后时间来到了5月中旬,这时春招基本也结束了,然后我开始投递简历,期间只是约到了几家下场面试。工资也只有6-7k,到现在我不知道该怎么办了。已经没有当初学习的心劲了,好累呀,但是又不知道该干什么去。在家就是打游戏,boss简历投一投。每天日重一次。26秋招都说是针对26届的人,25怎么办。我好绝望。要不要参加考公、考研、央国企这些的。有没有大佬可以帮帮我。为什么感觉别人找工作都是顺其自然的事情,我感觉自己每一步都在艰难追赶。八股文背了又忘背了又忘,我每次都花很长时间去理解他,可是现在感觉八股、项目都忘完了。真的已经没有力气再去学习了。图片是我的简历,有没有大哥可以指正一下,或者说我应该走哪条路,有点不想在找工作了。
码客明:太累了就休息一下兄弟,人生不会完蛋的
如果实习可以转正,你会不...
点赞 评论 收藏
分享
醉蟀:你不干有的是人干
点赞 评论 收藏
分享
评论
6
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务