单位质量最大价值问题
来源:互联网 发布:mac键盘切换输入法 编辑:程序博客网 时间:2024/04/29 18:36
描述:
有n个物品,单个物品的质量为w(weigh),价值为v(value),要从n个物品中选取k个,求再所有的选取方案中,能获得的最大单位质量价值。也就是k个物品总的价值V / 总的质量W。保留两位小数。
说明:
一般最先想到的方法是把每个物品按照单位价值排序,从大到小贪心进行选取。但这种方法是不正确的。举一个反例就好了。
比如说:n = 3, k = 2,(w, v) = {(2,2),(5,3),(2,1)},按照之前的策略应该选第一和第二物品,得到的平均价值为5/7 = 0.714。
但如果我们选择第一和第三个物品的话,结果就是3/4 = 0.75。所以说要想别的办法。
定义条件 C(x):= 可以选择使得单位重量的价值不小于x
原问题变成了求满足C(x)的最大x的问题。如何判断C(x)为真呢,假设我们选了k个物品,组成的集合为S,那么它们的单位质量价值是 Σv / Σw。
因此就变成了判断是否存在S满足条件 Σv / Σw >= x,变形得到 Σ(vi - x * wi) >= 0 。
因此,对vi - x * wi 的值进行排序,贪心的进行选取,最后问题变成了
C(x):((vi - x * wi) 从大到小排列中前k个和不小于0) 每次判断排序依次复杂度O(nlogn)。
完整实现代码如下:
#include <iostream>#include <algorithm>using namespace std;const int MAX_N = 1000;const double MAX_X = 1000000.0;int n, k;int w[MAX_N], v[MAX_N];double y[MAX_N];// v - x * wbool C(double x){for (int i = 0; i < n; i++)y[i] = v[i] - x * w[i];sort(y, y + n);// 计算y数组中从大到小前k个数的和double sum = 0.0;for (int i = 0; i < k; i++)sum += y[n - 1 - i];return sum >= 0;}int main(){cin >> n >> k;for (int i = 0; i < n; i++)cin >> w[i] >> v[i];double lb = 0.0, ub = MAX_X;for (int i = 0; i < 100; i++){double mid = (lb + ub) / 2;if (C(mid))lb = mid;elseub = mid;}printf("%.2f\n", ub);}
结果:
ps:这个主要在《挑战程序设计竞赛》上看到的,感觉非常巧妙。搬上来跟大家分享下。也强烈推荐这本书。
0 0
- 单位质量最大价值问题
- 最大价值
- 最大价值
- 博客价值评估 (单位: 人民币)
- 动态规划实例(七):01背包问题最大价值
- 最大价值(DP)
- 求最大价值
- MTU[最大传输单位]
- MTU 最大传输单位
- 动态规划问题 -- 背包问题 单价不等水果 装入固定容量背包 最大价值问题
- CRM数据质量到底价值几何?
- 用质量成本体现质量管理的价值
- 质量在中国中小企业中价值几何?
- 练习赛11.1.最大价值
- 最大价值和,多重背包
- 数组最大价值(DP)
- 最大总质量,整备质量,核定载质量
- 单位用人问题
- Linux Socket编程
- 移动App仅需几分钟 五大云开发平台推荐
- dup和dup2函数
- 解压和生成 system.img&data.img ( ext4格式)
- 归并排序
- 单位质量最大价值问题
- HDU Common Subsequence 最长公共子序列
- Java泛型详解
- EXP-00091和IMP-00010解决办法
- 再会poi
- MIDL error: 'annotation' (zz)
- mysql保存中文乱码的原因和解决办法
- 微信公众账号
- IOS使用视图控制器和视图(五)使用 UISegmentedControl 做简单选项分组