2021牛客国庆集训派对day5

A、gpa

题意:给出n,k,数组s和c求在删除最多k对{s,c}的情况下∑s[i]*c[i]/∑s[i]的值最大
思路:我们可以二分答案x,然后对s[i]c[i]-xs[i]排序并求前缀和,在前缀和小于0的时候当前位置到末尾都需要删除,然后看删除的个数是否小于等于k。
代码:

#include
typedef long long ll;
typedef unsigned long long ull;
#define int ll
#define pii pair<int,int>
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define rrep(i,a,b) for(int i=(a);i>=(b);--i)
using namespace std;
const double pi=acos(-1.0);
const double eps=1e-8;
const int mod=998244353;
const int INF=0x3f3f3f3f;
const int LINF=0x3f3f3f3f3f3f3f3f;
const int MAXN=1e5+10;
double s[MAXN];
double c[MAXN];
double num[MAXN];
double sum[MAXN];
int n,k;
bool check(double x)
{
   
    for(int i=1;i<=n;++i)
    {
   
        num[i]=s[i]*c[i]-x*s[i];
    }
    sort(num+1,num+1+n,greater<double>());
    for(int i=1;i<=n;++i)
    {
   
        sum[i]=sum[i-1]+num[i];
    }
    for(int i=1;i<=n;++i)
    {
   
        if(sum[i]<0)
        {
   
            return n-i+1<=k;
        }
    }
    return 1;
}
void solve()
{
   
    cin>>n>>k;
    for(int i=1;i<=n;++i) cin>>s[i];
    for(int i=1;i<=n;++i) cin>>c[i];
    double l=0,r=1e18;
    int sum=0;
    while(r-l>eps)
    {
   
        sum++;
        if(sum==1000) 

你可能感兴趣的:(图论,算法,深度优先)