洛谷-P2569 股票交易

股票交易#

dp + 单调队列优化

题目要求只能从第 wi1 天买入或卖出

dp[i][j] 表示在第 i 天且当天持有 j 股的最大利润

有三种状态转移方式:

  1. 不买也不卖

dp[i][j]=dp[i1][j]

  1. 从第 w1i 天买入

dp[i][j]=maxk=jASij1(dp[w1i][k]APi(jk))

将常数提出来之后可以考虑用单调队列优化

dp[i][j]=maxk=jASij1(dp[w1i][k]+kAPi)jAPi

  1. 从第 w1i 天卖出

dp[i][j]=maxk=j+1j+BSi(dp[w1i][k]+BPi(kj))

同理,提取常数后用单调队列优化

dp[i][j]=maxk=j+1j+BSi(dp[w1i][k]+kBPi)jBPi

#include <iostream>
#include <iostream>
#include <cstdio>
#include <deque>
#include <algorithm>
using namespace std;
typedef long long ll;
#define pii pair<ll, ll>
const int maxn = 2010;
const ll inf = 0x3fffffffffffffff;
ll dp[maxn][maxn];

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t, p, w;
    cin >> t >> p >> w;
    for(int i=0; i<=t; i++) for(int j=0; j<=p; j++) dp[i][j] = -inf;
    dp[0][0] = 0;
    for(int i=1; i<=t; i++)
    {
        ll ap, bp, as, bs;
        cin >> ap >> bp >> as >> bs;
        int pre = max(0, i - w - 1);
        deque<pii>q;
        for(int j=p; j>=0; j--)
        {
            while(q.size() && q.back().first <= dp[pre][j] + j * bp)
                q.pop_back();
            q.push_back({dp[pre][j] + j * bp, j});
            while(q.front().second > j + bs) q.pop_front();
            dp[i][j] = max(dp[i-1][j], q.front().first - j * bp);
        }
        while(q.size()) q.pop_front();
        for(int j=0; j<=p; j++)
        {
            while(q.size() && q.back().first <= dp[pre][j] + j * ap)
                q.pop_back();
            q.push_back({dp[pre][j] + j * ap, j});
            while(q.front().second < j - as) q.pop_front();
            dp[i][j] = max(dp[i][j], q.front().first - j * ap);
        }
    }
    ll ans = -inf;
    for(int j=0; j<=p; j++)
        ans = max(ans, dp[t][j]);
    cout << ans << endl;
    return 0;
}
posted @   dgsvygd  阅读(47)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
点击右上角即可分享
微信分享提示
主题色彩