POJ 2976 Dropping tests 01分数规划 模板 二分&&Dinkelbach
来源:互联网 发布:拍照软件 编辑:程序博客网 时间:2024/06/10 23:31
Description
In a certain course, you take n tests. If you get ai out of bi questions correct on test i, your cumulative average is defined to be
Given your test scores and a positive integer k, determine how high you can make your cumulative average if you are allowed to drop any k of your test scores.
Suppose you take 3 tests with scores of 5/5, 0/1, and 2/6. Without dropping any tests, your cumulative average is
However, if you drop the third test, your cumulative average becomes
Input
The input test file will contain multiple test cases, each containing exactly three lines. The first line contains two integers, 1 ≤ n ≤ 1000 and 0 ≤ k < n. The second line contains n integers indicating ai for all i. The third line contains n positive integers indicating bi for all i. It is guaranteed that 0 ≤ ai ≤ bi ≤ 1, 000, 000, 000. The end-of-file is marked by a test case with n = k = 0 and should not be processed.
Output
For each test case, write a single line with the highest cumulative average possible after dropping k of the given test scores. The average should be rounded to the nearest integer.
Sample Input
3 1
5 0 2
5 1 6
4 2
1 2 7 9
5 6 7 9
0 0
Sample Output
83
100
Hint
To avoid ambiguities due to rounding errors, the judge tests have been constructed so that all answers are at least 0.001 away from a decision boundary (i.e., you can assume that the average is never 83.4997).
大意:
即从 a[i] 和 b[i] 中取出对应的 k 组数 要求 sigma(a[i])/sigma(b[i]) 最大,求这个最大值.
另一种显然的表示方法:
所谓的01分数规划问题就是指这样的一类问题,给定两个数组,a[i]表示选取i的收益,b[i]表示选取i的代价。如果选取i,定义x[i]=1,否则x[i]=0。
每一个物品只有选或者不选两种方案,求一个选择方案即从其中选取k组a[i]/b[i],使得
01分数规划问题主要包含一般的01分数规划、最优比率生成树问题、最优比率环问题等。
对应这个目标式,我们可以整理出一个判别式
用二分答案的思想
当 f(r)>0 时,显然我们还可以取更大的 r 来使得 f(r) 逼近 0
当 f(r)<0 时,我们应取更小的 r
每次得到 r,更新
易得 题目求最大值时,我们排序后取大的 k 个数
题目求最小值时,我们排序后取小的 k 个数
二分:
#include <iostream>#include <cstring>#include <string>#include <cstdio>#include <algorithm>using namespace std;typedef long long ll;#define LL long long#define mem(s,t) memset(s,t,sizeof s)#define pb push_back#define inf 0x3f3f3f3fconst ll MAXN = 2e4+10;const double eps=1e-6;struct node{ int a,b; double v;}p[MAXN];bool cmp(node x,node y){ return x.v>y.v;}int main(){ int n,m,k; while(~scanf("%d%d",&n,&m) && n+m){ k=n-m; for(int i=0;i<n;i++) scanf("%d",&p[i].a); for(int i=0;i<n;i++) scanf("%d",&p[i].b); double l=0,r=100,mid; while(l+eps<r){ mid=(l+r)/2; for(int i=0;i<n;i++){ p[i].v=p[i].a-mid*p[i].b; } sort(p,p+n,cmp); double sum=0; for(int i=0;i<k;i++){ sum+=p[i].v; } if(sum>0) l=mid; else r=mid; } printf("%.0f\n",l*100); }}
Dinkelbach法
类似二分,由于 f(r)是可以逐次逼近 0 的.
上次得到答案 r ,用 r 去计算
当 R 和 r 相等(eps)时,r 即为最终答案,否则迭代下去计算.
学习到的牛顿迭代法,需要一个估计值,以及要求迭代过程是收敛的,在本题里表现为:
每次确定一个 r,都可以通过表达式接着确定下一个更精确的 R
%%%
#include <iostream>#include <cstring>#include <string>#include <cstdio>#include <algorithm>#include <cmath>using namespace std;typedef long long ll;#define LL long long#define mem(s,t) memset(s,t,sizeof s)#define pb push_back#define inf 0x3f3f3f3fconst ll MAXN = 1e4+10;const double eps=1e-6;struct node{ double a,b; double v;}p[MAXN];bool cmp(node x,node y){ return x.v>y.v;}int main(){ int n,m,k; while(~scanf("%d%d",&n,&m) && n+m){ k=n-m; for(int i=0;i<n;i++) scanf("%lf",&p[i].a); for(int i=0;i<n;i++) scanf("%lf",&p[i].b); double r=0,R=0; double x=0,y=0; for(int i=0;i<k;i++) x+=p[i].a,y+=p[i].b; r=x/y; while(fabs(R-r)>=eps){ r=R; for(int i=0;i<n;i++){ p[i].v=p[i].a-r*p[i].b; } sort(p,p+n,cmp); double x=0,y=0; for(int i=0;i<k;i++){ x+=p[i].a; y+=p[i].b; } R=x/y; } printf("%.0f\n",r*100); }}//POJ里用int和db混用会T 大概是强制转换&&迭代次数太多了??全用db就过了
需要注意的是,很多01分数规划都是要求保留整数,这时要看清是四舍五入(%.0f)还是截断整数(显式转换为int)
- POJ 2976 Dropping tests 01分数规划 模板 二分&&Dinkelbach
- poj 2976: Dropping tests(01分数规划--Dinkelbach算法)
- POJ 2976 Dropping tests 01分数规划Dinkelbach算法
- POJ 2976-Dropping tests(01分数规划_二分||Dinkelbach算法)
- poj Dropping tests 01分数规划---Dinkelbach算法
- poj Dropping tests 01分数规划---Dinkelbach算法
- poj 2976 Dropping tests(01分数规划+二分)
- POJ 2976 Dropping tests (01分数规划+二分)
- POJ 2976 Dropping tests 01分数规划 二分解法
- POJ - 2976 Dropping tests(二分 + 01分数规划)
- POJ 2976 Dropping tests 01分数规划
- POJ 2976 Dropping tests 01分数规划
- poj-2976-Dropping tests-01分数规划
- POJ 2976 Dropping tests 01分数规划
- 【POJ】2976 Dropping tests 01分数规划
- [poj 2976]Dropping tests 01分数规划
- POJ 2976 Dropping tests (01分数规划)
- POJ 2976 Dropping tests(01分数规划)
- Python核心编程第二版第六章学习笔记
- Java实现敏感词过滤
- Python学习文件(File)方法
- 数据链路层帧传输的三个基本问题
- phpstorm 配置
- POJ 2976 Dropping tests 01分数规划 模板 二分&&Dinkelbach
- Windows环境安装tesseract-ocr 4.00并配置环境变量
- keras for attention
- nginx一 之负载均衡介绍
- 软件开发常用词汇中英文对照
- Andrid网络变化实时监听操作
- 为了拍电影买比特币,电影赔了,比特币却赚了回来!
- 基于图像的流行排序算法
- C#操作ACCESS如何判断某表格存在