#0/1分数规划#AT1807 食塩水
题目
从\(n\)对数\((w_i,p_i)\)中选择\(k\)对使得
\[\frac{\sum_{i=1}^k w'_i*p'_i}{\sum_{i=1}^k w'_i}
\]
最大
分析
若可行解为\(t\),
\[\frac{\sum_{i=1}^k w'_i*p'_i}{\sum_{i=1}^k w'_i}\geq t
\]
化简得到
\[\sum_{i=1}^k w'_i*(p'_i-t)\geq 0
\]
那可以对于每一对\((w_i,p_i)\)求出\(w_i*(p_i-t)\)
贪心从大到小选择,若前\(k\)个和不少于0,则此解为可行解
代码
#include <cstdio>
#include <cctype>
#include <algorithm>
#define rr register
using namespace std;
const int N=1011;
int n,k; double w[N],a[N],c[N];
inline bool check(double mid){
rr double now=0;
for (rr int i=1;i<=n;++i) a[i]=w[i]*(c[i]-mid);
sort(a+1,a+1+n);
for (rr int i=1;i<=k;++i) now+=a[n-i+1];
return now>=0;
}
signed main(){
scanf("%d%d",&n,&k);
for (rr int i=1;i<=n;++i)
scanf("%lf%lf",&w[i],&c[i]);
rr double l=0,r=100;
for (rr int i=1;i<101;++i){
rr double mid=(l+r)/2;
if (check(mid)) l=mid;
else r=mid;
}
return !printf("%.9lf",l);
}