【BZOJ1816】[Cqoi2010]撲克牌 二分
阿新 • • 發佈:2017-05-18
desc har 其余 特殊 二分 names soft sam led
3 4
1 2 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。
【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,即牌的種數和joker的個數。第二行包含n個整數ci,即每種牌的張數。Output
輸出僅一個整數,即最多組成的套牌數目。Sample Input
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。
題解:二分,然後亂搞~
#include <cstdio> #include <cstring> #include <iostream> using namespace std; int n; int c[60]; int solve(int x) { int i,sum=0; for(i=1;i<=n;i++) { if(c[i]<x) sum+=x-c[i]; if(sum>x||sum>c[0]) return 0; } return 1; } int main() { scanf("%d%d",&n,&c[0]); int i,l=1<<30,r=0,mid; for(i=1;i<=n;i++) scanf("%d",&c[i]),l=min(l,c[i]); r=c[0]+l+1; while(l<r) { mid=l+r>>1; if(solve(mid)) l=mid+1; else r=mid; } printf("%d",l-1); return 0; }
【BZOJ1816】[Cqoi2010]撲克牌 二分