标签:stream names define isp sts 最大 http += clu
有n对数,记做\(\{a_i,b_i\}\),现在你只能不选择k对数,使选出来的数a之和除以b之和乘以100最大,\(1 \leq k ≤ n ≤ 1000\)。
显然看到某某和除以某某和,就想到了分数规划,于是设
\[ans=\frac{\sum_{i=1}^nx_ia_i}{\sum_{i=1}^nx_ib_i}\]
所以二分式为
\[\sum_{i=1}^nx_i(a_i-ans\times b_i)\]
实际上问题即变成选出n-k对\((a_i-ans\times b_i)\)使之最大,于是我们最自然是考虑排序优化,而这个时间复杂度是我们所能接受的,接着按
照二分或者迭代去做即可。
参考代码:
二分
#include <iostream>
#include <cstdio>
#include <algorithm>
#define il inline
#define ri register
#define db double
#define exact 0.00000001
int n,k;
db a[2001],b[2001],c[2001];
using namespace std;
il bool check(db);
il db dfs(db,db);
int main(){
int i,j;
while(scanf("%d%d",&n,&k),n||k){
for(i=1;i<=n;++i)scanf("%lf",&a[i]);
for(i=1;i<=n;++i)scanf("%lf",&b[i]);
printf("%0.f\n",dfs(0,1));
}
return 0;
}
il bool check(db s){
int i;db j(0);
for(i=1;i<=n;++i)c[i]=a[i]-s*b[i];
sort(c+1,c+n+1);for(i=k+1;i<=n;++i)j+=c[i];
if(j>exact)return true;return false;
}
il db dfs(db l,db r){
db mid;
while(r-l>exact){
mid=(l+r)/2;
if(check(mid))l=mid+exact;
else r=mid-exact;
}return (l+r)*50;
}
迭代
#include <iostream>
#include <cstdio>
#include <algorithm>
#define il inline
#define ri register
#define db double
#define exact 0.00000001
using namespace std;
struct save{
db data;int id;
il bool operator<(const save&x){
return data<x.data;
}
}c[2001];
db a[2001],b[2001];
int main(){
int n,k,i;db l,mom,son;
while(scanf("%d%d",&n,&k),n||k){
for(i=1;i<=n;++i)scanf("%lf",&a[i]);
for(i=1;i<=n;++i)scanf("%lf",&b[i]);
l=0;while(true){
for(i=1;i<=n;++i)c[i].data=a[i]-b[i]*l,c[i].id=i;
sort(c+1,c+n+1),mom=0,son=0;
for(i=k+1;i<=n;++i)son+=a[c[i].id],mom+=b[c[i].id];
if(son/mom-l>exact)l=son/mom;
else break;
}printf("%.0f\n",l*100);
}
return 0;
}
标签:stream names define isp sts 最大 http += clu
原文地址:https://www.cnblogs.com/a1b3c7d9/p/10802919.html