HackerRank--Stock Maximize

HackerRank–Stock Maximize

题目描述

给定N天的股票价格。每一天用户可以选择买入一股,或者卖出自己拥有的任意股,或者什么交易都不做。求可以获得的最大的利润。


分析

目标很直观,希望找到一个最大价格的日子卖掉之前买进的所有股票,所以需要记录当前股票价格的所有极大值。
如果当前价格大于之前的极大值,就应该更新极大值为今天的价格,并放弃在之前那一天卖出,这一过程可能会超过多个之前的极大值,那么之前的极大值都可以也应该被舍弃;如果当前价格小于之前的值,应当等待后面的更高价格来判断当前值的去留。
我们只需要记录极大值出现的天数是第几天,然后每次把两个极大值之间的价格用后面的极大值都减去再求和即可。
需要用数组存储所有的价格,不能用常数空间,然后可以用栈来维护当前极大值,因为只需要从末端考虑。

数据范围

天数 N 可以有 50000,股票价格是 1 到 100000,int32 会溢出,结果要用 long long /int64。

实现

#include <stack>
#include <vector>
#include <iostream>

using namespace std;

int main(){
    int T;
    cin >> T;
    int N;
    for (int tt = 0; tt < T; ++tt) {
        cin >> N;
        vector<int> ve(N);
        int p;
        for (int i = 0; i < N; ++i) 
            cin >> ve[i];

        stack<int> st;
        st.push(0);
        for (int i = 1; i < N; i++) {
            int last_max_i;
            while (!st.empty()) {
                last_max_i = st.top();
                if (ve[i] > ve[last_max_i]) {
                    st.pop();
                } else {
                    break;
                }
            }
            st.push(i);
        }
        long long ans = 0;
        while (!st.empty()) {
            int sale_day = st.top();
            st.pop();
            int last_sale_day = st.empty() ? -1 : st.top();
            for (int j = sale_day - 1; j > last_sale_day; j--) {
                ans += ve[sale_day] - ve[j];
            }
        }
        cout << ans << endl;
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值