#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);
}
posted @ 2021-03-05 20:11  lemondinosaur  阅读(59)  评论(0编辑  收藏  举报