题目描述
Farmer John要带着他的NN头奶牛,方便起见编号为1 \ldots N1…N,到农业展览会上去,参加每年的达牛秀!他的第ii头奶牛重量为w_iwi,才艺水平为t_iti,两者都是整数。 在到达时,Farmer John就被今年达牛秀的新规则吓到了:
(一)参加比赛的一组奶牛必须总重量至少为WW(这是为了确保是强大的队伍在比赛,而不仅是强大的某头奶牛),并且
(二)总才艺值与总重量的比值最大的一组获得胜利。
FJ注意到他的所有奶牛的总重量不小于WW,所以他能够派出符合规则(一)的队伍。帮助他确定这样的队伍中能够达到的最佳的才艺与重量的比值。
输入输出格式
输入格式:
输入的第一行包含NN(1 \leq N \leq 2501≤N≤250)和WW(1 \leq W \leq 10001≤W≤1000)。下面NN行,每行用两个整数w_iwi(1 \leq w_i \leq 10^61≤wi≤106)和t_iti(1 \leq t_i \leq 10^31≤ti≤103)描述了一头奶牛。
输出格式:
请求出Farmer用一组总重量最少为WW的奶牛最大可能达到的总才艺值与总重量的比值。如果你的答案是AA,输出1000A1000A向下取整的值,以使得输出是整数(当问题中的数不是一个整数的时候,向下取整操作在向下舍入到整数的时候去除所有小数部分)。
输入输出样例
输入样例#1: 复制
3 15 20 21 10 11 30 31
输出样例#1: 复制
1066
说明
在这个例子中,总体来看最佳的才艺与重量的比值应该是仅用一头才艺值为11、重量为10的奶牛,但是由于我们需要至少15单位的重量,最优解最终为使用这头奶牛加上才艺值为21、重量为20的奶牛。这样的话才艺与重量的比值为(11+21)/(10+20) = 32/30 = 1.0666666...,乘以1000向下取整之后得到1066。
供题:Brian Dean
题解:01分数规划二分答案,背包dp求最大值判断是否合法。
#include<bits/stdc++.h>
#define f(i,l,r) for(i=(l);i<=(r);i++)
#define ff(i,r,l) for(i=(r);i>=(l);i--)
using namespace std;
const int MAXN=255,MAXM=1005;
double EPS=1e-5;
struct Node{
int w,t;
double c;
}a[MAXN];
int n,m;
double f[MAXM];
bool check(double ans)
{
int i,j;
f(i,1,n){
a[i].c=1.0*a[i].t-a[i].w*ans;
}
f(i,0,m) f[i]=-1e20;
f[0]=0;
f(i,1,n){
ff(j,m,0){
f[min(m,j+a[i].w)]=max(f[min(m,j+a[i].w)],f[j]+a[i].c);
}
}
return f[m]>=0;
}
int main()
{
ios::sync_with_stdio(false);
int i,j;
double l=0,r=0;
cin>>n>>m;
f(i,1,n){
cin>>a[i].w>>a[i].t;
r+=a[i].t;
}
while(r-l>EPS){
double mid=(l+r)/2;
if(check(mid)) l=mid;
else r=mid;
}
cout<<(int)(1000*l)<<endl;
return 0;
}