NYOJ-914 Youth的最大化(贪心)
Posted codinRay
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了NYOJ-914 Youth的最大化(贪心)相关的知识,希望对你有一定的参考价值。
Youth的最大化
时间限制: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且小于单个物品的最大单位价值。求出单个物品的最大单位价值,然后二分查找即可。
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <stdbool.h>
4 #define imax(x,y) (x>y?x:y)
5 #define MAXN 10005
6 int n, k;
7 double w[MAXN], v[MAXN];
8 int i;
9 double need[MAXN];
10 int compare(const void * p1, const void * p2) {
11 return *(double *)p1 < *(double *)p2 ? 1 : -1;
12 }
13 bool judge(double x) {
14 // 算出当前物品达到均值x的代价,
15 //负数表示比均值小,正数反之
16 for (i = 0; i < n; i++) {
17 need[i] = v[i] - x*w[i];
18 }
19
20 //将need数组从大到小排序
21 qsort(need, n, sizeof(need[0]), compare);
22
23 // 取前k个,算出它们所需代价之和
24 // 若为正,则代表超过均值,代表均值不够大,向右区间查找;为负反之
25 double all_need = 0;
26 for (i = 0; i < k; i++) {
27 all_need += need[i];
28 }
29 return all_need >= 0 ? true : false;
30 }
31 double binary_search(double right) {
32 double left = 0;
33 while (right - left > 0.00001) {
34 double mid = (left + right) / 2;
35 if (judge(mid))
36 left = mid;
37 else
38 right = mid;
39 }
40 return left;
41 }
42 int main(void)
43 {
44 while (scanf("%d %d", &n, &k)!=EOF) {
45 double max_ratio = 0;
46 for (i = 0; i < n; i++) {
47 scanf("%lf %lf", &w[i], &v[i]);
48 max_ratio = imax(max_ratio,(v[i]/w[i]));
49 }
50 //printf("%lf\n", max_ratio);
51 double res = binary_search(max_ratio);
52 printf("%.2lf\n", res);
53 }
54 return 0;
55 }
以上是关于NYOJ-914 Youth的最大化(贪心)的主要内容,如果未能解决你的问题,请参考以下文章
LeetCode 剑指Offer 42 连续子数组的最大和[贪心] HERODING的LeetCode之路
FlutterFlutter 全面屏适配 ( 需要适配的情况 | Android 设置最大宽高比 | 使用 SafeArea 进行全面屏适配 | 使用 MediaQuery 进行全面屏适配 )(代码片