zoukankan      html  css  js  c++  java
  • [Luogu] P5815 [CQOI2010]扑克牌

    Description

    你有(n)种牌,第(i)种牌的数目为(c_i)​。另外有一种特殊的牌(joker),它的数目是(m)。你可以用每种牌各一张来组成一套牌,也可以用一张(joker)和除了某一种牌以外的其他牌各一张组成(1)套牌。比如,当(n=3)时,一共有(4)种合法的套牌:(,,,{1,2,3},{J,2,3},{1,J,3},{1,2,J})

    给出(n)(m)(c_i),你的任务是组成尽量多的套牌。每张牌最多只能用在一副套牌里(可以有牌不使用)。

    Solution

    转化一下题意就很好做了。

    现在有(n)竹子(每根竹子有(c_i)节,每节竹子高度为 (1)),可以通过消耗一点法力值使某一根竹子的某两节之间再长出特殊的一节,现在有(m)点法力值,我需要在保证同一高度只能有不超过 (1)节特殊的竹节的情况下,使最矮的那根竹子高度尽可能的高。

    所以直接二分答案就好了。

    (check)里面就直接算出最短竹子长(x)时,要消耗的法力值(sum)。注意(sum)除了要(le{m}),还要(le{x}),因为同一高度只能有不超过 (1)节特殊的竹节。

    Code

    #include <bits/stdc++.h>
    
    using namespace std;
    
    #define ll long long
    
    int n, m, res, l, r, mn = 2e9, c[55];
    
    int read()
    {
    	int x = 0, fl = 1; char ch = getchar();
    	while (ch < '0' || ch > '9') { if (ch == '-') fl = -1; ch = getchar();}
    	while (ch >= '0' && ch <= '9') {x = (x << 1) + (x << 3) + ch - '0'; ch = getchar();}
    	return x * fl;
    }
    
    int check(int x)
    {
    	ll sum = 0ll;
    	for (int i = 1; i <= n; i ++ )
    		sum += max((x - c[i]), 0);
    	return sum <= min(x, m);
    }
     
    int main()
    {
    	n = read(); m = read();
    	for (int i = 1; i <= n; i ++ ) c[i] = read(), mn = min(mn, c[i]);
    	l = 0; r = 2e9;
    	while (l <= r)
    	{
    		int mid = (l + r) >> 1;
    		if (check(mid)) res = mid, l = mid + 1;
    		else r = mid - 1;
    	}
    	printf("%d
    ", res);
    	return 0;
    }
    
  • 相关阅读:
    过滤xml文件内容
    python接口自动化之通过接口模拟一通电话的多段对话
    浅谈python性能与优化
    监控之Linux系统监控命令大全
    mysql windows 5.7 安装版下载地址
    liunx 安装jdk
    下载文件,后台执行没问题,没下载文件
    spring boot thymeleaf
    spring security文档地址
    redis 可视化工具下载地址
  • 原文地址:https://www.cnblogs.com/andysj/p/13972423.html
Copyright © 2011-2022 走看看