poj之旅——2976C++

来源:互联网 发布:java api接口测试工具 编辑:程序博客网 时间:2024/05/02 02:17

二分法解决最大平均值的模式:

设[l,r)为可行区间,l表示最小可行数,r表示最大可能可行数,取mid,Check(mid)

,可行则l=mid,否则r=mid。

Check(mid):

设平均值为mid,如果可行的话,则有x=sum{a[i]}/sum{b[i]}最优解>mid,所以mid<=sum{a[i]}/sum{b[i]}

即mid*sum{b[i]}<=sum{a[i]}

sum{a[i]}-mid*sum{b[i]}>=0

sum{a[i]-mid*b[i]}>=

故定义新数组c[i]=a[i]-mid*b[i]

按照从大到小排序,选取前k个(k为所需数目)

若和大于零,表明Check(mid)可行。


参考程序:

#include<cstdio>#include<algorithm>#include<functional>#define maxn 2100using namespace std;long long a[maxn],b[maxn],c[maxn];int n,m;bool Check(int k){for (int i=0;i<n;i++)c[i]=a[i]-k*b[i];sort(c,c+n,greater<long long>());long long sum=0;for (int i=0;i<n-m;i++)sum+=c[i];return sum>=0;}int main(){while (scanf("%d%d",&n,&m)==2 && (n || m)){for (int i=0;i<n;i++){scanf("%lld",&a[i]);a[i]*=10000;}for (int i=0;i<n;i++)scanf("%lld",&b[i]);int l=0,r=10001;while (l+1<r){int mid=(l+r)>>1;if (Check(mid))l=mid;else r=mid;}printf("%.0f\n",l/100.0);}return 0;}


1 0
原创粉丝点击