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 }