題目:
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).
題意:
給你兩個數字N和K,代表有N個成績,讓你去掉的成績個數;
下面的兩行代表每一個考試的成績,讓你求出來去除掉K個成績後 的最大值;
思路:
假設 ai / bi >=x,那麼ai - x*bi >= 0;可以直接對於x 進行二分搜索,計算出每一個成績對應的ai - x * bi 的值存成 s[ i ] ;
那麼只需要把計算出來的s數組進行排序,選擇出來最大的前K個數值即可,那麼這K個數值的和就是最大的結果;
注意輸出結果即可;
擴展:
關於01分數規劃,查看了幾篇博客纔有了一點頭緒,那麼就用來理解這一道題的代碼吧;
令F(x)=ai - x*bi,那麼這就可以看成一個一元一次的方程式:F(x)=A - x*B,即F(x)= - B *x + A;
那麼我們可以知道這條直線和Y軸的交點是 A(A >=0,因爲 A = ai ),和X軸的交點是A / B ,斜率是 - B(小於0);
要求出來 x 的最大值,那麼這條直線和X軸的交點就是最大值;
那麼我們就可以來枚舉 x 的值,找出來一條垂直於X軸的直線L,看直線 L 和直線F(x)的交點;
如果交點的值在X軸上邊,那麼這個 x 的值就是小於最大解;
如果交點的值在X軸下邊,那麼這個 x 的值就是大於最大解;
這個就是二分的依據了,成功的解決了代碼中二分依據的問題;
代碼如下:
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int N=1010;
int n,k;
int a[N],b[N];
double s[N];
double low,high,mid;
int judge(double x)
{
for(int i=1;i<=n;i++)
{
s[i]=a[i]-x*b[i];
}
sort(s+1,s+n+1);
double ans=0;
for(int i=n;i>k;i--)///選擇最大的K個值;
{
ans+=s[i];
}
return ans>=0;
}
void solve()
{///01分數規劃;
low=0;
high=1;
while(high-low>1e-6)///注意判斷條件;
{
mid=(low+high)/2.0;
if(judge(mid))
low=mid;
else
high=mid;
}
printf("%.0lf\n",low*100);///注意輸出;
return ;
}
int main()
{
while(~scanf("%d%d",&n,&k))
{
if(n==0&&k==0)///輸入結束;
break;
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
for(int i=1;i<=n;i++)
{
scanf("%d",&b[i]);
}
solve();
}
return 0;
}