华为机考真题 -- 贪心歌手

题目描述:

歌手准备从 A 城去 B 城参加演出

1. 按照合同,他必须在 T 天内赶到;
2. 歌手途径 N 座城市;
3. 歌手不能往回走;
4. 每两座城市之间需要的天数都可以提前获知;
5. 歌手在每座城市都可以在路边卖唱赚钱。经过调研,歌手提前获知了每座城市卖唱的收入预期。如果在一座城市第一天卖唱可以赚 M,后续每天的收入会减少 D (第二天赚的钱是 M-D,第三天是 M-2D…)。如果收入减到 0就不会再少了;
6. 歌手到达后的第二天才能开始卖唱。如果今天卖过唱,第二天才能出发;

问贪心的歌手最多可以赚多少钱?

输入描述:

第一行两个数字 T 和 N,中间用空格隔开,T 代表总天数; N 代表路上经过 N 座城市,其中0 < T < 1000,0 < N < 100;

第二行 N+1 个数字,中间用空格隔开,代表每两座城市之间耗费的时间,其总和<=T;

接下来 N 行,每行两个数字 M 和 D,中间用空格隔开,代表每个城市的收入预期,其中0 < M < 1000,0 < D < 100;

输出描述:

一个数字,代表歌手最多可以赚多少钱,并以回车键结束

示例1:

输入
10 2
1 1 2
120 20
90 10

输出
540
说明
总共 10 天,路上经过 2 座城市。 路上共花 1+1+2=4 天。 剩余 6 天最好的计划是在第一座城市待 3 天,在第二座城市待 3 天。 在第一座城市赚的钱:120 + 100 + 80 = 300 在第二座城市赚的钱:90 + 80 + 70 = 240,共 300 +240 = 540

示例2:

输入
10 3
1 1 2 3
120 20
90 10
100 20

输出
320

C++源码:

#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
#include <numeric>

using namespace std;

int maxProfit(int T, int N, const vector<int>& travelTimes, const vector<pair<int, int>>& cities) {
    int allTime = accumulate(travelTimes.begin(), travelTimes.end(), 0);
    int leftDays = T - allTime;

    priority_queue<int, vector<int>, greater<>> profits;

    for (const auto& city : cities) {
        int M = city.first;
        int D = city.second;
        for (int day = 1; day <= leftDays; ++day) {
            int dailyProfit = M - (day - 1) * D;
            if (dailyProfit > 0 && (profits.size() < leftDays || dailyProfit > profits.top())) {
                if (profits.size() == leftDays) profits.pop();
                profits.push(dailyProfit);
            }
            else {
                break;
            }
        }
    }

    int maxProfit = 0;
    while (!profits.empty()) {
        maxProfit = maxProfit + profits.top();
        profits.pop();
    }
    return maxProfit;
}

int main() {
    int T, N;
    cin >> T >> N;
    vector<int> travelTimes(N + 1);
    for (int i = 0; i <= N; ++i) {
        cin >> travelTimes[i];
    }

    vector<pair<int, int>> cities(N);
    for (int i = 0; i < N; ++i) {
        cin >> cities[i].first >> cities[i].second;
    }

    int P = maxProfit(T, N, travelTimes, cities);
    cout << P << endl;

    system("pause");
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值