时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
Special Judge, 64bit IO Format: %lld
题目描述
Kanade selected n courses in the university. The academic credit of the i-th course is s[i] and the score of the i-th course is c[i].
At the university where she attended, the final score of her is
Now she can delete at most k courses and she want to know what the highest final score that can get.
输入描述:
The first line has two positive integers n,k The second line has n positive integers s[i] The third line has n positive integers c[i]
输出描述:
Output the highest final score, your answer is correct if and only if the absolute error with the standard answer is no more than 10-5
示例1
输入
3 1 1 2 3 3 2 1
输出
2.33333333333
说明
Delete the third course and the final score is
备注:
1≤ n≤ 105 0≤ k < n 1≤ s[i],c[i] ≤ 10^3
题目大意:
给出序列s和c,求在最多删除k个课程后最大。
分析:
01分数规划模板题,读者可以参看这篇文章https://blog.csdn.net/hhaile/article/details/8883652
这里直接给出这一题的思路
首先根据01分数规划,我们令,变换后,令
这样只要二分d,对p[i]排序,先取n-k个,剩下的k个只要p[i]<=0时后面的都不需要了(显然是对答案有负贡献的)。
唯一比较麻烦的是精度问题,目测1e-8应该够了(大概)
#include<iostream>
#include<string>
#include<cstring>
#include<vector>
#include<map>
#include<algorithm>
#include<queue>
#include<set>
#include<cstdio>
#include<functional>
#include<iomanip>
#include<cmath>
#include<stack>
#include<iomanip>
#include<functional>
#include<iomanip>
#include<bitset>
#define lson l,m
#define rson m+1,r
using namespace std;
typedef long long LL;
typedef unsigned long long ull;
typedef pair<int, int> pii;
const int maxn = int(1e5) + 100;
const int BN = 30;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const LL mod = 998244353;
const double eps = 1e-8;
int n, k;
int s[maxn], c[maxn];
double p[maxn];
bool cmp(double a, double b) {
return a > b;
}
bool check(double mid) {
for (int i = 0; i < n; i++)
p[i] = s[i] * (c[i] - mid);
sort(p, p + n, cmp);
double ans = 0;
for (int i = 0; i < n-k; i++)
ans += p[i];
for (int i = n - k; i < n; i++)
if (p[i] > 0)
ans += p[i];
if (ans > -eps) return true;
return false;
}
int main() {
//ios::sync_with_stdio(false);
//cin.tie(0);
//freopen("D:\\cpp\\comper\\3224\\8.in", "r", stdin);
//freopen("D:\\cpp\\\comper\\8.in", "w", stdout);
while (~scanf("%d%d", &n, &k)) {
for (int i = 0; i < n; i++)
scanf("%d", &s[i]);
for (int i = 0; i < n; i++)
scanf("%d", &c[i]);
double l = 0.0, r = 1000.0;
while (r - l > eps) {
double mid = (l + r)*0.5;
if (check(mid))l = mid;
else r = mid;
}
printf("%.10lf\n", l);
}
return 0;
}