Yougth的最大化
时间限制:
1000 ms | 内存限制:
65535 KB
难度:
4
-
描述
-
Yougth现在有n个物品的重量和价值分别是Wi和Vi,你能帮他从中选出k个物品使得
最大吗?-
输入
-
有多组测试数据
每组测试数据第一行有两个数n和k,接下来一行有n个数Wi和Vi。
(1<=k=n<=10000) (1<=Wi,Vi<=1000000)
输出
- 输出使得单位价值的最大值。(保留两位小数) 样例输入
-
3 2 2 2 5 3 2 1
样例输出
-
0.75
题目分析:k个物品单位重量的最大价值一定不会超过单个物品单位价值的最大值,并且一定不小于0,这样我们就求出了最终答案所在的区间。然后利用二分压缩区间,顺便贪心法,进行统计,直到求出最终结果。
-
#include<iostream> #include<algorithm> #include<cstdio> using namespace std; #define eps 1e-4 int n,k; const int N=100010; double w[N],p[N],pos[N],maxp; int cmp(double a, double b) { if(a>b) return 1; return 0; } bool judge(double x) { for(int i = 0 ; i <n ; i++) { pos[i]=p[i] - w[i] * x; } sort(pos,pos+n,cmp); double sum=0; for(int i=0 ; i<k; i++)//统计前k大的剩余价值是否大于0 sum=sum+pos[i]; if(sum>=0) return true; else return false; } double search() { double left = 0; double right = maxp; while(right-left>eps)//二分法查找,逐渐确认最大的价值 { double mid = (left + right)/2; if(judge(mid)) left = mid; else right =mid; } return left; } int main() { int m,x,y,ans1,ans2; while(cin>>n>>k) { maxp=0; for(int i=0; i<n; i++) { scanf("%lf %lf",&w[i],&p[i]); if(p[i]/w[i]>maxp) maxp=max(p[i]/w[i],maxp);//寻找出做大的单位重量的价值 } printf("%.2lf\n",search()); } return 0; }
-
有多组测试数据