hdu 3418 Beautiful Dream数学题

来源:互联网 发布:梦幻群侠传3优化版攻略 编辑:程序博客网 时间:2024/05/02 00:28

链接:http://acm.hdu.edu.cn/showproblem.php?pid=3418

题意:大概就是有n种数字,从1 到n每种数字有a[i]个,要你把它分成k组,每组数有m个不相同的数,问k最大是多大

题解:对答案进行二分,从min(a[i])  到   sum/m 进行二分答案。 如何判定答案是否可行?假设当前判断k是否可行,那么只要a[i] > k 那么a[i] > k的部分就不能取(因为取了肯定会有重复,根据鸽巢原理),对于a[i]求和,a[i] 大于k 我们取k,得到sum。比较一下sum/m 和 k的大小,大于等于则可行(你可以用反证法想一下)。

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;typedef __int64 LL;const LL INF = 0x3f3f3f3f3f3f3f3fLL;LL a[105];int judge(LL mid,LL n,LL m){    LL sum = 0;    for(int i = 0; i <n; ++i)        if(a[i] >= mid) sum += mid;        else sum += a[i];    if(sum >= m * mid) return 1;    return 0;}int main(){   LL n,m,sum,minx;    while(~scanf("%I64d%I64d",&n,&m)){        sum = 0,minx = INF;        for(int i = 0; i < n; ++i){            scanf("%d",&a[i]);            minx = min(minx,a[i]);            sum += a[i];        }        LL L = minx,R = sum/m,mid,ans;        while(L <= R){            mid = (R + L) >> 1;            if(judge(mid,n,m)){                ans = mid;                L = mid + 1;            }else R = mid - 1;        }        printf("%I64d\n",ans);    }    return 0;}


0 0