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
-
就因为把need数组放函数里面错了三次。
-
思路:k个物品的最大单位价值 一定大于0且小于单个物品的最大单位价值。求出单个物品的最大单位价值,然后用二分查找即可。
-
#include <cstdio> #include <cstring> #include <algorithm> #define MAX 10000+10 using namespace std; double w[MAX], v[MAX]; double max_aver;//单个物品中最大均值 double need[MAX]; int n, k; int find(double o) { int i, j; for(i = 0; i < n; i++) { need[i] = v[i] - o * w[i];//算出当前物品达到均值o的代价,若达不到代价就是负的,若超过代价就是正的 } sort(need, need+n); double sum = 0; for(i = 0; i < k; i++) { sum += need[n-i-1]; } if(sum >= 0)//所需付出代价是正的 证明均值不够大 继续向上查找 return 1; else//付出代价是负的,均值过大,向下查找 return 0; } void search(double r) { double l = 0; while(r - l > 0.00001) { double mid = (l+r)/2; if(find(mid))//查询在中点右方 l = mid; else//在左方 r = mid; } printf("%.2lf\n", l); } int main() { int i, j; while(~scanf("%d%d", &n, &k)) { max_aver = 0; for(i = 0; i < n; i++) { scanf("%lf%lf", &w[i], &v[i]); max_aver = max(max_aver, v[i]/w[i]); } search(max_aver);//从最大平均值开始搜索 } return 0; }
- 有多组测试数据