01分数规划
2022/8/24 6:53:08
本文主要是介绍01分数规划,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
01分数规划
经典例题:POJ2976
给定 \(n\) 个物品的价值 \(a\) 和 花费 \(b\) ,取其中的 \(k\) 个物品,求 \(\sum a[i] / \sum b[i]\) 的最大值。
题解:
假设 \(\sum a[i] / \sum b[i] = x\) ,则:
当 \(x\) 不是最优解时,\(\sum a[i] / \sum b[i] \ge x\) 成立,则存在一种组合使 \(\sum(a[i]-x\times b[i]) > 0\) 成立
为了尽可能让解更大,我们需要尽可能使该式成立,这样就可以继续找更大的解。
为了尽可能使该式成立,我们需要取最大的 \(k\) 个 \((a[i]-x\times b[i])\) ,
若 \(\sum(a[i]-x\times b[i]) > 0\) 成立, \(x\) 就不是最优解 ;
也就是说不断二分 \(x\) 的值,就可以找到最优解:
设 \(cheknum=\sum(a[i]-x\times b[i])\) ,
若 \(cheknum > 0\) , 则 \(x\) 可以更大
若 \(cheknum=0\) , 则 \(x\) 是最优解
若 \(cheknum<0\) , 则 \(x\) 需要更小
代码:
bool chek(int x) { rep(i,1,n) c[i]=a[i]-x*b[i]; sort(c+1,c+n+1,cmp);//从大到小 int res=0; rep(i,1,k) res+=c[i]; return res >= 0; } void solv() { int l=0,r=maxx; while(r - l > eps) { double mid = (r+l)/2; if(chek(mid)) l=mid;//更大 else r=mid;//变小 } printf("%lf",l); }
这篇关于01分数规划的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-22[开源]10.3K+ Star!轻量强大的开源运维平台,超赞!
- 2024-11-21Flutter基础教程:新手入门指南
- 2024-11-21Flutter跨平台教程:新手入门详解
- 2024-11-21Flutter跨平台教程:新手入门与实践指南
- 2024-11-21Flutter列表组件教程:初学者指南
- 2024-11-21Flutter列表组件教程:新手入门指南
- 2024-11-21Flutter入门教程:初学者必看指南
- 2024-11-21Flutter入门教程:从零开始的Flutter开发指南
- 2024-11-21Flutter升级教程:新手必读的升级指南
- 2024-11-21Flutter升级教程:轻松掌握Flutter版本更新