01分数规划

01 分数规划

此人在福州市 2025 国庆集训 Day2 T3 因为不会分数规划取得了 \(0\) 分的好成绩!

问题

给定两个长度为 \(n\) 的序列 \(a,b\)。需要从中选出 \(k\) 个下标 \(idx\),使得 \(\frac{\sum^k_{i=1}a_{idx_i}}{\sum^k_{i=1}b_{idx_i}}\) 最大或最小。

下文以最大为例子。

解法

我们考虑一个数字 \(x\),使 \(\frac{\sum^k_{i=1}a_{idx_i}}{\sum^k_{i=1}b_{idx_i}}\ge x\)。那么我们再来稍微推推式子,有:

\[\sum^k_{i=1}a_{idx_i}\ge x\cdot \sum^k_{i=1}b_{idx_i}\\ \sum^k_{i=1}a_{idx_i}-x\cdot \sum^k_{i=1}b_{idx_i}\ge 0\\ \sum^k_{i=1}(a_{idx_i}-x\cdot b_{idx_i})\ge 0\\ \]

所以我们可以把每个下标都给重新赋上权值,即 \(v_i=a_i-x\cdot b_i\),最后排个序。

因为是综合要大等于 \(0\),所以显然取前 \(k\)最大的是最优的。

那么如何确定 \(x\) 呢?

考虑直接二分。二分到一个 \(x\),代进去 check 一下,如果可以则更新左端点,不行则更新右端点。

因为如果一个 \(x\) 代进去发现小于 \(0\),即不合法,那么大于 \(x\) 的所有数更不可能合法。

综上,一般情况下的时间复杂度是 \(O(n\log^2 n)\)

例题

福州市 2025 国庆集训 Day2 T3 course

模板题。

代码:

#include<bits/stdc++.h>
using namespace std;
typedef double db;
const int N=1e5+5;
int n,k;
db c[N],t[N],a[N];
bool cmp(db a,db b){return a>b;}
bool check(db x)
{
	for(int i=1;i<=n;++i)
		a[i]=c[i]-x*t[i];
	sort(a+1,a+n+1,cmp);
	db ans=0.0;
	for(int i=1;i<=k;++i)
		ans+=a[i];
	return ans<=0;
}
int main(){
	ios::sync_with_stdio(0);
	cin>>n>>k;
	for(int i=1;i<=n;++i)cin>>c[i];
	for(int i=1;i<=n;++i)cin>>t[i];
	db l=0.0,r=1.0,mid;
	while(l<r&&r-l>0.0001)
	{
//		cout<<l<<' '<<r<<' '<<mid<<'\n';
		mid=(l+r)/2.0;
		if(check(mid))r=mid;
		else l=mid;
	}
	cout<<fixed<<setprecision(3)<<l<<'\n';
	return 0;
}

洛谷 P1570 KC 喝咖啡

也差不多是模板题,双倍经验了属于。

#include<bits/stdc++.h>
using namespace std;
typedef double db;
const int N=205;
int n,m;
db v[N],c[N],val[N];
bool cmp(db a,db b){return a>b;}
bool check(db x)
{
	for(int i=1;i<=n;++i)
		val[i]=v[i]-x*c[i];
	sort(val+1,val+n+1,cmp);
	db ans=0.0;
	for(int i=1;i<=m;++i)
		ans+=val[i];
	return ans>=0.0;
}
int main(){
	ios::sync_with_stdio(0);
	cin>>n>>m;
	for(int i=1;i<=n;++i)cin>>v[i];
	for(int i=1;i<=n;++i)cin>>c[i];
	db l=0.0,r=1000.0,mid;
	while(l<r&&r-l>0.00001)
	{
//		cout<<l<<' '<<r<<' '<<mid<<'\n';
		mid=(l+r)/2.0;
		if(check(mid))l=mid;
		else r=mid;
	}
	cout<<fixed<<setprecision(3)<<l<<'\n';
	return 0;
}

完结撒花。

posted @ 2025-10-03 17:36  Atserckcn  阅读(11)  评论(0)    收藏  举报