bzoj 1816 扑克牌

题目大意:

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

思路:

可以发现答案是单调的

我们可以二分答案

判定的时候,如果不到mid的牌就必须要用Joker代替 相当于有mid-a[i]张Joker要打出

最后判断Joker是否够用

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<cstdlib>
 5 #include<cstring>
 6 #include<algorithm>
 7 #include<vector>
 8 #include<queue>
 9 #define inf 2139062143
10 #define ll long long
11 #define MAXN 2001000
12 using namespace std;
13 inline int read()
14 {
15     int x=0,f=1;char ch=getchar();
16     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
17     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
18     return x*f;
19 }
20 int n,m,a[51],ans;  
21 int check(int x)  
22 {
23     int t=min(m,x);
24     for(int i=1;i<=n;i++){if(a[i]<x) {t-=(x-a[i]);if(t<0)return 0;}}
25     return 1;  
26 }
27 int main()  
28 {
29     n=read(),m=read();
30     for(int i=1;i<=n;i++) a[i]=read();
31     int l=1,r=inf,mid;
32     while(l<=r)
33     {
34         mid=(l+r)>>1;
35         if(check(mid)) ans=mid,l=mid+1;  
36         else r=mid-1;
37     }
38     printf("%d",ans);  
39 }
View Code
posted @ 2018-02-12 18:49  jack_yyc  阅读(156)  评论(0编辑  收藏  举报