分数规划+01背包
n种物品,两种属性,求比值最大值,标准的01分数规划问题。
考虑这种问题的套路解法,先二分一个答案mid,得到如下式子:
把乘过去在移项,提公因式得:。
最后我们做体积为W的01背包,如果重量超出W,则把它算在上,就解决了题目中重量至少为W的限制。
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10,INF=1e9;
const double eps=1e-5;
int n,W,w[N],t[N];
double l,r,c[N],f[N];
bool check(double mid){
for(int i=1;i<=n;i++) c[i]=(double)t[i]-mid*w[i];
for(int i=1;i<=W;i++) f[i]=-INF;
for(int i=1;i<=n;i++){
for(int j=W;j>=0;j--){
if(j+w[i]>=W) f[W]=max(f[W],f[j]+c[i]);
else f[j+w[i]]=max(f[j+w[i]],f[j]+c[i]);
}
}
return f[W]>=0;
}
int main(){
ios::sync_with_stdio(false);
cin>>n>>W;
for(int i=1;i<=n;i++) cin>>w[i]>>t[i],r+=(double)t[i];
while(l+eps<=r){
double mid=(l+r)/2;
if(check(mid)) l=mid;
else r=mid;
}
cout<<(int)(l*1000)<<endl;
return 0;
}