分析:
二分答案后利用0/1背包检查合法性即可。
代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
const int MAXN=255;
int n,W;
int w[MAXN],t[MAXN];
double c[MAXN],f[1005];
inline bool check(double mid){
for(int i=1;i<=n;i++) c[i]=t[i]-w[i]*mid;
for(int i=0;i<=W;i++) f[i]=-1e9;f[0]=0;
for(int i=1;i<=n;i++){
for(int j=W;j+w[i]>=W&&j+1;j--) f[W]=std::max(f[W],f[j]+c[i]);
for(int j=W-1;j;j--) if(j>=w[i]) f[j]=std::max(f[j],f[j-w[i]]+c[i]);
}
return f[W]>=0;
}
int main(){
scanf("%d%d",&n,&W);
for(int i=1;i<=n;i++) scanf("%d%d",&w[i],&t[i]);
double l=0,r=1e6+5,ans;
while(r-l>1e-8){
double mid=(l+r)/2;
if(check(mid)) ans=mid,l=mid;
else r=mid;
}
printf("%.0lf\n",floor(ans*1000));
return 0;
}