码迷,mamicode.com
首页 > 其他好文 > 详细

初始状态机dp 股票买卖IV

时间:2021-02-27 13:18:50      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:int   main   代码   sizeof   void   www   不同   com   ems   

状态机dp感觉还挺有趣的 主要就是利用dp数组 将题意说表达的要求细分为不同的状态 达到削减时间的目的
比如https://www.acwing.com/problem/content/1059/ acwing的这道股票购买IV

这道题给了一组数字我可以在任意时间购入一个股票 并在之后卖出 但在同一时间内我只能持有一股 同时有个交易次数的上限
依照此描述 我们就可以设置一个dp数组f[i][j][k]表示 在前i个物品中买j个物品所获得的收益 其中k = 0表示不持有股票 k = 1表示持有股票

这样我们就可以得到一个状态转移方程

f[i, j, 0]可由在f[i - 1, j, 0]和f[i - 1, j, 1] + w[i]所表示
即在前i - 1个物品中购买j个物品,同时没有持有股票 和 在前i - 1个物品中购买j个物品,此刻卖出股票 表示
f[i, j, 1]可由f[i - 1, j, 1]和f[i - 1, j - 1, 0] - w[i]所表示
即在前i - 1个物品中购买j个物品,并且持有股票 和在前i - 1个物品中购买j - 1个物品,此刻购买股票 表示

因为并不一定交易次数越多,收益就越多 显而易见,最后持有股票一定比卖出股票的收益低 所以答案就在f[n, 0 ~ m, 0]中存在
下面是代码hhhh

const int N = 100010, M = 110; 
int n, m, l[N];
int f[N][M][2];

int main(void)
{
    cin >> n >> m;
    
    for(int i = 1; i <= n; i ++ ) cin >> l[i];
    memset(f, -0x3f, sizeof f);
    for(int i = 0; i <= n; i ++ ) f[i][0][0] = 0;
    
    for(int i = 1; i <= n; i ++ )
        for(int j = 1; j <= m; j ++ )
        {
            f[i][j][0] = max(f[i - 1][j][0], f[i - 1][j][1] + l[i]);
            f[i][j][1] = max(f[i - 1][j][1], f[i - 1][j - 1][0] - l[i]);
        }
    
    int ans = 0;
    for(int i = 0; i <= m; i ++ )
        ans = max(ans, f[n][i][0]);
    cout << ans;
}

初始状态机dp 股票买卖IV

标签:int   main   代码   sizeof   void   www   不同   com   ems   

原文地址:https://www.cnblogs.com/yzzlqyxc/p/14454063.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!