• [SCOI 2010]股票交易


    Description

    题库链接

    一共 (t) 天,第 (i) 天股票买入价 (ap_i),最多可买 (as_i) 股;卖出价 (bp_i),最多可买 (bs_i) 股。并且在任何时候你最多持有 (maxp) 股股票,相邻两次交易(买入或卖出)要间隔 (w+1) 天。默认初始你有无限的钱,问 (t) 天后你最多能赚多少钱。

    (1leq w< tleq 2000,1leq maxpleq 2000)

    Solution

    首先默认 (w = w+1)

    (f_{i,j}) 表示第 (i) 天持有 (j) 张股票时,获得的最大收益。

    考虑买入,(f_{i,j}=maxlimits_{j-kleq as_i}f_{i-w,k}+(k-j) imes ap_i=-j imes ap_i+maxlimits_{j-kleq as_i}f_{i-w,k}+k imes ap_i)。发现 (j) 这一维可以单调队列优化。

    卖出同理,综上复杂度为 (O(t imes maxp))

    Code

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 2000+5, inf = 1e9;
    
    int t, maxp, w, ap[N], bp[N], as[N], bs[N], f[N][N];
    int q[N], head, tail;
    
    int main() {
        scanf("%d%d%d", &t, &maxp, &w); ++w;
        for (int i = 1; i <= t; i++)
            scanf("%d%d%d%d", &bp[i], &ap[i], &bs[i], &as[i]);
        for (int i = 1; i <= maxp; i++) f[0][i] = -inf;
        for (int i = 1; i <= w; i++) {
            for (int j = 1; j <= bs[i]; j++)
                f[i][j] = max(-bp[i]*j, f[i-1][j]);
            for (int j = bs[i]+1; j <= maxp; j++)
                f[i][j] = max(-inf, f[i-1][j]);
        }
        for (int i = w+1; i <= t; i++) {
            q[head = tail = 1] = 0;
            for (int j = 1; j <= maxp; j++) {
                while (j-q[head] > bs[i]) ++head;
                f[i][j] = f[i-w][q[head]]+(q[head]-j)*bp[i];
                while (head <= tail && f[i-w][q[tail]]+q[tail]*bp[i] < f[i-w][j]+j*bp[i]) --tail;
                q[++tail] = j;
            }
            q[head = tail = 1] = maxp;
            for (int j = maxp-1; j >= 0; j--) {
                while (q[head]-j > as[i]) ++head;
                f[i][j] = max(f[i-w][q[head]]+(q[head]-j)*ap[i], f[i][j]);
                while (head <= tail && f[i-w][q[tail]]+q[tail]*ap[i] < f[i-w][j]+j*ap[i]) --tail;
                q[++tail] = j;
            }
            for (int j = 0; j <= maxp; j++) f[i][j] = max(f[i][j], f[i-1][j]);
        }
        int ans = 0;
        for (int i = 0; i <= maxp; i++) ans = max(ans, f[t][i]);
        printf("%d
    ", ans);
        return 0;
    }
  • 相关阅读:
    Excel 2016 Power View选项卡不显示的问题
    Base64编码
    MAPI错误0x80040107
    命令行界面 (CLI)、终端 (Terminal)、Shell、TTY的区别
    C函数调用过程原理及函数栈帧分析
    SIFT(Scale-invariant feature transform) & HOG(histogram of oriented gradients)
    Jupyter NoteBook 的快捷键
    endnote插入参考文献后的对齐方式和缩进空格
    赏月斋源码共享计划 第四期 约瑟夫问题
    LRU和LFU的区别
  • 原文地址:https://www.cnblogs.com/NaVi-Awson/p/12238958.html
Copyright © 2020-2023  润新知