来源于: http://hi.baidu.com/dlutnocow/blog/item/3a23c5ab17de8abccb130c31.htmlhdu 3418 二分 凑 ★★★ 这题我做不出,看edward_mj的 edward_mj那里也有一种不是二分的,就是每次不断计算平均值,对于cnt[i]>avg的,cnt[i]=avg(去掉多余的物品) 直到没有多余的物品。
 /**//*
题意:n种物品,每种个数为cnt[i],一个人获得至少m种才算开心,问能是多少人开心
主要思路是将n种物品压缩成m种(m<=n),答案就是最少的那种最大化
二分答案limit
对于每个cnt[i],如果大于limit,取为limit
最后将这n个cnt[i]累加到sum,判断sum是否≥limit*m
(大概就是多余的不要,少的凑一下,看能不能使最少的那个>=limit)
*/
#include<cstdio>
#include<algorithm>
using namespace std;

const long long INF = 1LL<<50;//太大的话*100会溢出!!

int cnt[105];
int n,m;

bool chk(long long x)
  {
long long sum = 0;
for(int i=0;i<n;i++)
sum+=min((long long)cnt[i],x);
return sum>=x*m;
}
int main()
  {
while(~scanf("%d%d",&n,&m))
 {
for(int i=0;i<n;i++)
scanf("%d",&cnt[i]);
long long left = 0,right = INF;
while(right-left>1)
 {
long long mid = (right+left)>>1;
if(chk(mid))left=mid;
else right=mid;
}
printf("%I64d\n",left);
}
return 0;
}
zoj 3334 ★★★ 也即求能使m个医生同时工作的最长时间 类似于凑,将n种凑成m种,使最短的那个最长
 /**//*
题意:m个医生检查n个病人,每个病人需要时间为t[i]
每个病人可以分为多次检查,每次一个医生 但不能同时被多个医生检查
对于医生,要么m个同时工作,要么只有1个工作 求最少的检查时间
当然,能m个医生同时检查的先同时检查
而求n个人能被m个医生同时检查的最长时间跟hdu3418类似
使凑成m个的最少的那个最长!

二分枚举时间limit
时间大于limit的变为limit
累加总时间,看是否≥limit*m

然后剩余的只能一个医生工作了
*/
#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std;

const double EPS = 1e-12;
const int MAXN = 1005;

double t[MAXN];
int n,m;

bool chk(double limit)
  {
double sum=0.0;
for(int i=0;i<n;i++)
sum+=min(limit,t[i]);
return sum>limit*m-EPS;//>=
}
double cal(double tot)//计算能被m个医生同时检查的最长时间
  {
if(m>n)return 0.0;

double left = 0,right = tot;
for(int i=0;i<60;i++)
//while(right-left>EPS) --> TLE
 {
double mid=(left+right)/2.0;
if(chk(mid))left=mid;
else right=mid;
}
return left;
}
int main()
  {
while(~scanf("%d%d",&m,&n))
 {
double tot = 0.0;
for(int i=0;i<n;i++)
 {
scanf("%lf",&t[i]);
tot+=t[i];
}
printf("%.4f\n",tot-(m-1)*cal(tot));
}
return 0;
}
hdu 2730
 /**//*
题意: 一个工具箱里有n种颜色,每种50ml 。而任意三种数量为x颜色
mix能凑出数量x的灰色 现给出每种颜色的还有灰色的需求量
求最少需要购买的工具箱 跟hdu 3418类似

可二分枚举工具箱的个数
然后再检查能否满足各种颜色,还有灰色的数量需求

*/
#include<cstdio>
#include<algorithm>

using namespace std;

const int INF = 10000000;

int cnt[15],_cnt[15];
int n,gray;

bool _chk(int limit)
  {
int sum = 0;
for(int i=0;i<n;i++)
sum+=min(limit,_cnt[i]);
return sum>=limit*3;
}

int cal()
  {
int left = 0,right = INF;
while(right-left>1)
 {
int mid=(right+left)>>1;
if(_chk(mid))left=mid;
else right=mid;
}
return left;
}

bool chk(int x)
  {
for(int i=0;i<n;i++)
 {
_cnt[i]=50*x-cnt[i];
if(_cnt[i]<0)return false;
}
return cal()>=gray;
}

int main()
  {
//freopen("in","r",stdin);
//freopen("out","w",stdout);
while(scanf("%d",&n),n)
 {
for(int i=0;i<n;i++)
scanf("%d",&cnt[i]);
scanf("%d",&gray);
int low = -1 , high = INF;//low=-1 high=0也可以取到
while(high-low>1)
 {
int mid=(high+low)>>1;
if(chk(mid))high = mid;
else low = mid;
}
printf("%d\n",high);
}
return 0;
}
|
|
常用链接
随笔分类
Links
搜索
最新评论

|
|