末了 endless - 2020 NOI Online #2 (入门组)

题目:https://www.luogu.com.cn/problem/P6473

题解

前缀和 + 二分
dp[i] 表示用i个魔法,最多需要多少年

Code

#include <bits/stdc++.h>
using namespace std;

int mg[200010], n;
double dp[200010], L, v;
//为了后续方便,L和v直接用double了
//dp[i] 表示用i个魔法 最多需要多少年

void binary(double k){//二分
    int left = 1, right = n, best = -1;//best记录最佳值,即最少用多少次魔法
    while (left <= right) {
        int mid = ceil((left + right) >> 1);
        if(dp[mid] < k){
            left = mid + 1;
        }else{
            best = mid;
            right = mid - 1;
        }
    }
    printf("%d\n", best);
    return ;
}

int main(){
//    freopen("endless.in","r",stdin);
//    freopen("endless.out","w",stdout);
    scanf("%d%lf%lf", &n, &L, &v);
    for(int i = 1; i <= n; i++){
        scanf("%d", &mg[i]);
    }
    sort(mg + 1, mg + int(n) + 1);//排序,以保证dp[i]是i个魔法的最大值
    int t, m;
    dp[0] = L / v;//初始化
    for(int i = 1; i <= n; i++){
        dp[i] = dp[i-1] * v + mg[int(n) - i + 1];
        dp[i] /= v;
    }
    scanf("%d", &m);
    while (m--) {
        scanf("%d", &t);
        if(t >= dp[n]){//无法满足条件
            printf("-1\n");
            continue;
        }
        if(t < L / v){//不需要使用魔法
            printf("%d\n", 0);
            continue;
        }
        binary(t);
    }
    return 0;
}

posted @ 2020-04-25 22:40  LT-Y  阅读(233)  评论(0)    收藏  举报