zoukankan      html  css  js  c++  java
  • Codeforces614D Skills

    题意:n个科目,每个科目最高分为A,现在最多能提高m分。最后权值是两种分数算法之和,第一种算法是达到A分的科目个数*cf,第二种算法是最低分*cm。求提高分数之后,最后的权值最大是多少。并打印出方案。

    题解:最大值有x个,最小值为y,那么权值就是w = cf*x+cm*y可以发现这里有两个变量,考虑枚举一个,二分另外一个

    #include <bits/stdc++.h>
    #define maxn 100010
    #define INF 0x3f3f3f3f
    typedef long long ll;
    using namespace std;
    ll n, A, cf, cm, m, t1, t2;
    pair<ll, ll >a[maxn];
    ll sum[maxn], ma;
    ll cmp(pair<ll, ll >aa, pair<ll, ll >bb){
        return aa.second<bb.second;
    }
    ll f(ll x, ll r){
        ll l = 1, pos = -1;
        while(l<=r){
            ll mid = (l+r)>>1;
            if(a[mid].first <= x) l = mid+1, pos = mid;
            else r = mid-1;
        }
        return x*pos-(sum[pos]-sum[0]);
    }
    int main(){
        scanf("%lld%lld%lld%lld%lld", &n, &A, &cf, &cm, &m);
        for(ll i=1;i<=n;i++)
            scanf("%lld", &a[i].first), a[i].second = i;
        sort(a+1, a+n+1);
        for(ll i=1;i<=n;i++) sum[i] = sum[i-1]+a[i].first;
        for(ll i=0;i<=n;i++){
            ll t = m-(A*i-sum[n]+sum[n-i]);
            if(t < 0) break;
            ll l=1,r=A,mi=-1;
            while(l<=r){
                ll mid = (l+r)>>1;
                if(f(mid,n-i) <= t) l = mid+1, mi = mid;
                else r = mid-1;
            }
            ll temp = mi*cm+cf*i;
            if(ma < temp){
                ma = temp;
                t1 = i;
                t2 = mi;
            }
        }
        for(ll i=1;i<=n;i++){
            if(a[i].first < t2) a[i].first = t2;
            if(n-i+1 <= t1) a[i].first = A;
        }
        sort(a+1, a+1+n, cmp);
        printf("%lld
    ", ma);
        for(ll i=1;i<=n;i++)
            printf("%lld ", a[i].first);
        return 0;
    }
  • 相关阅读:
    Java 学习资料
    01 html5
    vscode 插件推荐
    08 css高级
    07 css定位
    06 css布局浮动
    05 css盒子
    04 css复合选择器 标签 行高
    03 css字体样式
    02 css基础选择器
  • 原文地址:https://www.cnblogs.com/Noevon/p/8660043.html
Copyright © 2011-2022 走看看