bzoj 1816 [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,即牌的種數和joker的個數。

第二行包含n個整數ci,即每種牌的張數。

Output

輸出僅一個整數,即最多組成的套牌數目。

Sample Input

3 4
1 2 3

Sample Output

3

HINT

樣例解釋

輸入數據表明:

一共有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。

一看ci就知道不是二分就是矩乘,顯然不用矩乘,二分可以組成x套牌就ok了

#include<stdio.h>
#include<algorithm>
using namespace std;
int c[100001],m,i,n,ans;
bool check(int x)
{
	int tmp=min(m,x);
	for(int i=1;i<=n;i++)
	{
		if(c[i]<x)
			tmp-=x-c[i];
		if(tmp<0)
			return 0;		
	}
	return 1;
}
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
		scanf("%d",&c[i]);
	int left=0,right=1e10;
	while(left<right)
	{
		int mid=(left+right)/2;
		if(check(mid))
			left=mid+1,ans=mid;			
		else
			right=mid;
	}
	printf("%d",ans);
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章