bzoj1816: [Cqoi2010]扑克牌

二分答案。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define rep(i,n) for(int i=1;i<=n;i++)
const int inf=0x7f7f7f7f;
int c[55],n,m;
bool check(int x){
	int cnt=min(x,m);
	rep(i,n) if(c[i]<x) {
		cnt-=x-c[i];
		if(cnt<0) return false;
	}
	return true;
}
void work(){
	int l=0,r=inf,ans;
	while(l<=r){
		int mid=(l+r)>>1;
		if(check(mid)) ans=mid,l=mid+1;
		else r=mid-1;
	}
	printf("%d\n",ans);
}
int main(){;
	scanf("%d%d",&n,&m);
	rep(i,n) scanf("%d",&c[i]);
	work();return 0;
}

  

1816: [Cqoi2010]扑克牌

Time Limit: 10 Sec  Memory Limit: 64 MB
Submit: 1784  Solved: 704
[Submit][Status][Discuss]

Description

你有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,你的任务是组成尽量多的套牌。每张牌最多只能用在一副套牌里(可以有牌不使用)。

Input

第一行包含两个整数n, m,即牌的种数和joker的个数。第二行包含n个整数ci,即每种牌的张数。

Output

输出仅一个整数,即最多组成的套牌数目。

Sample Input

3 4
1 2 3

Sample Output

3

样例解释
输入数据表明:一共有1个1,2个2,3个3,4个joker。最多可以组成三副套牌:{1,J,3}, {J,2,3}, {J,2,3},joker还剩一个,其余牌全部用完。

数据范围
50%的数据满足:2 < = n < = 5, 0 < = m < = 10^ 6, 0< = ci < = 200
100%的数据满足:2 < = n < = 50, 0 < = m, ci < = 500,000,000。

HINT

Source

[Submit][Status][Discuss]

时间: 2024-08-05 15:23:08

bzoj1816: [Cqoi2010]扑克牌的相关文章

bzoj1816: [Cqoi2010]扑克牌(二分答案判断)

1816: [Cqoi2010]扑克牌 题目:传送门 题解: 被一道毒瘤题搞残了...弃了坑来刷刷水题 一开始还想复杂了...结果发现二分水过: 二分答案...然后check一下,joker肯定尽量用mid次,那么哪种牌不够就补(因为每次只能补一种,所以如果次数用完就return false) 代码: 1 #include<cstdio> 2 #include<cstring> 3 #include<cstdlib> 4 #include<cmath> 5

【BZOJ1816】[Cqoi2010]扑克牌 二分

[BZOJ1816][Cqoi2010]扑克牌 Description 你有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,你的任务是组成尽量多的套牌.每张牌最多只能用在一副套牌里(可以有牌不使用). Input 第一行包含两个整数n, m

BZOJ 1816: [Cqoi2010]扑克牌( 二分答案 )

二分答案.. 一开始二分的初始右边界太小了然后WA,最后一气之下把它改成了INF... ------------------------------------------------------------------------ #include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #define rep( i , n ) for( int i = 0 ; i

bzoj 1816: [Cqoi2010]扑克牌

1 #include<cstdio> 2 #include<iostream> 3 using namespace std; 4 int l,r,m,n,a[60],ans; 5 bool pan(int x) 6 { 7 int a1=min(x,m); 8 for(int i=1;i<=n;i++) 9 if(a[i]<x) 10 { 11 a1-=x-a[i]; 12 if(a1<0) 13 return 0; 14 } 15 return 1; 16 }

[BZOJ 1816][Cqoi2010]扑克牌(二分答案)

题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1816 分析: 我先以为是道水题,但是要注意的是每套牌中Joker只能用1张的,所以就出现了可能目前每种牌的剩余牌数都够,但不一定不用Joker,然后就短路了…… 看了hzwer的blog顿时茅塞顿开,原来是二分…… 二分答案x,然后判定 判定的方法:注意每套牌顶多只有一个Joker,所以对于答案x,能用的Joker的最大数量是T=Min(x,m),然后枚举每种牌,将每种牌相对于答案x差的个数

[BZOJ 1816] [Cqoi2010] 扑克牌 【二分答案】

题目链接:BZOJ - 1816 题目分析 答案具有可以二分的性质,所以可以二分答案. 验证一个答案 x 是否可行,就累加一下各种牌相对于 x 还缺少的量,如果总和超过了 x 或 m ,就不可行. 因为,当使用的joker小于等于 x 时,才可以通过合适地安排顺序使得每组牌中至多有一张 joker . 代码 #include <iostream> #include <cstdlib> #include <cstring> #include <cstdio>

二分答案 扑克牌

1 program hehe; 2 var 3 n,m,i,j:longint; 4 c:array[0..50] of longint; 5 6 function min(a,b:longint):longint; 7 begin 8 if a>b then exit(b); 9 exit(a); 10 end; 11 12 function ok(a:longint):boolean; 13 var 14 f,t:longint; 15 begin 16 t:=min(a,m); 17 fo

大神刷题表

9月27日 后缀数组:[wikioi3160]最长公共子串 dp:NOIP2001统计单词个数 后缀自动机:[spoj1812]Longest Common Substring II [wikioi3160]最长公共子串 [spoj7258]Lexicographical Substring Search 扫描线+set:[poj2932]Coneology 扫描线+set+树上删边游戏:[FJOI2013]圆形游戏 结论:[bzoj3706][FJ2014集训]反色刷 最小环:[poj1734

bzoj1816 扑克牌

Description 你有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,你的任务是组成尽量多的套牌.每张牌最多只能用在一副套牌里(可以有牌不使用). Input 第一行包含两个整数n, m,即牌的种数和joker的个数.第二行包含n个整