Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 13732 | Accepted: 4817 |
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 npositive 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).
Source
01分数规划入门,使用Dinkelbach算法,在现有的可行解下,不断迭代得到最优解。
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <math.h>
#include <cmath>
#define mem0(a) memset(a,0,sizeof(a))
#define meminf(a) memset(a,0x3f,sizeof(a))
using namespace std;
typedef long long ll;
typedef long double ld;
typedef double db;
const int maxn=10005,inf=0x3f3f3f3f;
const ll llinf=0x3f3f3f3f3f3f3f3f;
const db eps=1e-6;
struct Pack{
db a,b,d;
};
Pack p[maxn];
bool cmp(Pack x,Pack y) {
return x.d<y.d;
}
db Dinkelbach(int n,int k) {
db ans=0,l;
while (true) {
l=ans;
int i; db s0,s1;
for (i=1;i<=n;i++) {
p[i].d=p[i].a-l*p[i].b;
}
sort(p+1,p+n+1,cmp);
s0=s1=0;
for (i=k+1;i<=n;i++) {
s0+=p[i].a;s1+=p[i].b;
}
ans=s0/s1;
if (fabs(l-ans)<eps) return ans;
}
}
int main() {
int n,k;
scanf("%d%d",&n,&k);
while (n||k) {
int i;
ll s1,s0;
s1=s0=0;
for (i=1;i<=n;i++)
scanf("%lf",&p[i].a);
for (i=1;i<=n;i++)
scanf("%lf",&p[i].b);
db ans=Dinkelbach(n,k);
printf("%.0lf\n",ans*100.0);
scanf("%d%d",&n,&k);
}
return 0;
}