给出每门课的绩点和学分,最多删除k个课,问你最多均绩多少
一开始想着,就是贪心一下,某种排序,但是显然不可以(事实上在这上面撒比了很久甚至最后还在想)
想到了二分,但是不知道怎么二分,为什么呢,因为不知道二分的单调性在哪里,就不行了.
这题的核心就在于,不是排序后二分,而是二分每个之后排序,这样就可以单调确定每个点的价值.
二分是很灵活的东西,可以在任何地方出现.
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <set>
#include <vector>
#include <cmath>
#include <iomanip>
#define debug(x) //std::cerr << #x << " = " << (x) << std::endl
using namespace std;
typedef long long LL;
const int MAXN = 2e5 + 17;
const int MOD = 1e9 + 7;
vector<pair<double,double > > all;
int c[MAXN],s[MAXN];
double a[MAXN];
int n,k;
bool judge(double x)
{
for (int i = 0; i < n; ++i)
{
a[i] = 1.0*all[i].second*(1.0*all[i].first-x);
}
sort(a, a+n);
double sum = 0;
for (int i = k; i < n; ++i)
{
sum += a[i];
}
return sum>=0;
}
int main()
{
#ifdef noob
freopen("Input.txt", "r", stdin);
freopen("Output.txt", "w", stdout);
#endif
cin>>n>>k;
for (int i = 0; i < n; ++i)
{
scanf("%d",c+i);
}
for (int i = 0; i < n; ++i)
{
scanf("%d",s+i);
}
for (int i = 0; i < n; ++i)
{
all.push_back({s[i],c[i]});
}
double l = 0.0,r = 100000000+1;
int tms = 100;
for (int i = 0; i < tms; ++i)
{
double mid = (l+r)/2.0;
if(judge(mid))
l = mid;
else
r = mid;
}
debug(l);
cout<<fixed<<setprecision(11)<<l<<endl;
return 0;
}
这题没做出要怪自己,思维不够.虽然很多人都说是模版题,也很多类似的,但是这个应该是有可能当场想出的