算法提高-动态规划-状态机模型

这篇具有很好参考价值的文章主要介绍了算法提高-动态规划-状态机模型。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

状态机 + 线性dp

AcWing 1049. 大盗阿福

这题比较简单,主要是学习一下状态机的模版(如何定义状态,dp方程如何推导)。
再学一个知识点:线性dp(i由i-1递推过来)可以用滚动数组优化空间复杂度

#include <iostream>
#include <algorithm>
#include <cstring>

const int N = 1e5 + 10;

int f[2][2];//滚动数组优化,线性dp都是可以用滚动数组优化的
int w[N];
int n;

void solve()
{
    memset(f, -0x3f, sizeof f);
    f[0][0] = 0;
    std::cin >> n;
    for (int i = 1; i <= n; ++ i)
    {
        std::cin >> w[i];
    }
    
    for (int i = 1; i <= n; ++ i)
    {
        f[i & 1][0] = std::max(f[(i - 1) & 1][0], f[(i - 1) & 1][1]);
        f[i & 1][1] = f[(i - 1) & 1][0] + w[i];
    }
    
    std::cout << std::max(f[n & 1][0], f[n & 1][1]) << std::endl;
}

int main()
{
    int T;
    std::cin >> T;
    while (T -- )
    {
        solve();
    }
    return 0;
}

AcWing 1057. 股票买卖 IV

限制购买天数

这里也是线性dp,当然可以用滚动数组优化,但是之前大盗阿福写过了,这里就朴素版本了

#include <iostream>
#include <cstring>

const int N = 1e5 + 10, Mk = 110;//N可以开2,即滚动数组优化,但是之前大盗阿福用过了,我这里就朴素版本的了

int f[N][Mk][2];
int w[N];
int n, m;

void solve()
{
    memset(f, -0x3f, sizeof f);
    f[0][0][0] = 0;
    std::cin >> n >> m;
    for (int i = 1; i <= n; ++ i)
    {
        std::cin >> w[i];
    }
    
    for (int i = 1; i <= n; ++ i)//枚举天数
    {
        for (int j = 0; j <= m; ++ j)//枚举交易数
        {
            //第三维状态,0是卖出,1是买入
            
            
        /*
        错误的递推公式
        我们应当先考虑j-1,j从0开始,因此我们需要先判断j不为0,但是如果如果只判断j=0的时候才给f[i][j][0]赋值,
        那么假如j = 0的时候f[i][0][0]就没有初始值了,因此我们要提前令 f[i][j][0] = f[i - 1][j][0]; 给它赋值
        f[i][j][0] = std::max(f[i - 1][j - 1][1] + w[i], f[i - 1][j][0]);
        f[i][j][1] = std::max(f[i - 1][j][0] - w[i], f[i - 1][j][1]);
        */
            f[i][j][0] = f[i - 1][j][0];
            if (j) f[i][j][0] = std::max(f[i - 1][j - 1][1] + w[i], f[i - 1][j][0]);
            f[i][j][1] = std::max(f[i - 1][j][0] - w[i], f[i - 1][j][1]);
        }
    }
    
    int res = -0x3f3f3f3f;
     for (int j = 0; j <= m; ++ j)
    {
         res = std::max(res, f[n][j][0]);//这里不用枚举i,直接n就行了
    }
    std::cout << res;
}

int main()
{
    solve();
    return 0;
}

AcWing 1058. 股票买卖 V

限制了卖出股票的第二天不能买入股票
这题的0状态不是卖出股票的那天,卖出股票的那天是状态2,不是卖出股票且空仓的那天才是状态0

#include <iostream>
#include <cstring>
const int N = 1e5 + 10;

int f[N][3];
int w[N];

int n;

void solve()
{
    memset(f, -0x3f, sizeof f);
    f[0][0] = 0;
    std::cin >> n;
    for (int i = 1; i <= n; ++ i)
    {
        std::cin >> w[i];
    }
    
    for (int i = 1; i <= n; ++ i)
    {
        //0:空仓(冷冻期的后一天)      1:持仓        2:冷冻期(那一天卖出了股票)(其实我们是在状态为2这一天卖出的股票)
        f[i][0] = std::max(f[i - 1][2], f[i - 1][0]);
        f[i][1] = std::max(f[i - 1][1], f[i - 1][0]- w[i]);//这里不能从f[i - 1][2]转移过来,因为卖出股票后,你无法在第二天买入股票 (即冷冻期为 1 天)。
        f[i][2] = f[i - 1][1] + w[i];//(其实我们是在状态为2这一天卖出的股票)
    }
    
    std::cout << std::max(f[n][0], f[n][2]);
    return ;
}

int main()
{
    solve();
    return 0;
}

AcWing 1053. 修复DNA

这题涉及ac自动机,有点难,后面再来看吧

线性DP+KMP自动机模型

AcWing 1052. 设计密码

这题暂时没ac,但我大概知道啥是状态机了,类似你给他一个数他可以将其对应到一个状态上。

在AcWing 1052. 设计密码中,题意是:n位密码S串,m位的T串,保证我们n位的密码不含m位的T串有多少种设计密码的方案?
我们枚举n位密码,每一位记为i,那么第i位有26种选择方案,第i位每种选择方案可以对应匹配到T串的一个位置,
(比如i匹配到了m的k位置,就是S串的i-k~i匹配T串的1~k,

由此我们发现这不正是kmp吗,他是一种在线算法可以在我们枚举位置i的时候 取出i - 1位置时匹配的长度或者T串中的哪个个位置)

如果一个都匹配不到那么就是T串的0位置,T串我们记录的时候下标从1~m。

因此我们保证我们枚举的每个S串中的位置i不能匹配到T串中的位置m即可,这样就可以保证S串中没有T串。

回到状态机的定义,i的每个字母选择对应T串中的一个位置,本题中合法的位置为T串的0~m - 1(位置m不合法,0是我们自己定义的一个都不匹配的时候的位置)共m个位置,因此我们回忆kmp算法模版,str[j + 1] ?= str[i](如果不想等j = ne[j],如果相等 j ++ ),T串中的每个位置j在状态机中能跳到哪个位置完全取决于S串中位置i上的字母,s串上位置i的字母有26种取值方式,因此状态机中m个点有26种不同的跳跃方式,状态机的图中一共有26 * m条边(可能会有重边),我们只要在入口0处跳n次并且最终不跳到位置m即可。

注意:做本题的时候y总用了偷懒的方法,不偷懒的话就是提前将m个位置的图建好,即预处理g[m][26]这个数组数组的值就是位置j上如果和位置i上的26字母中的k匹配的时候最终可以跳到哪个位置。
代码可以看这个博客课;
我自己wa的那个代码是从i-1转移到i,大部分题解是从i转移到i+1。文章来源地址https://www.toymoban.com/news/detail-606072.html

到了这里,关于算法提高-动态规划-状态机模型的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C++算法 —— 动态规划(3)多状态

    每一种算法都最好看完第一篇再去找要看的博客,因为这样会帮你梳理好思路,看接下来的博客也就更轻松了。当然,我也会尽量在写每一篇时都可以让不懂这个算法的人也能边看边理解。 动规的思路有五个步骤,且最好画图来理解细节,不要怕麻烦。当你开始画图,仔细阅

    2024年02月09日
    浏览(38)
  • 【状态压缩】【动态规划】【C++算法】691贴纸拼词

    视频算法专题 动态规划汇总 状态压缩 我们有 n 种不同的贴纸。每个贴纸上都有一个小写的英文单词。 您想要拼写出给定的字符串 target ,方法是从收集的贴纸中切割单个字母并重新排列它们。如果你愿意,你可以多次使用每个贴纸,每个贴纸的数量是无限的。 返回你需要拼

    2024年01月19日
    浏览(39)
  • 动态规划系列 | 状态机模型(上)| 练完这些就算入门了!

    用状态机模型求解动态规划问题,就是将原始问题用状态机模型进行表示,即 每个节点表示状态,每条边表示一个状态转移,边上的权值表示转移的代价或收益 。 状态机模型的目标是 找到一条从初始状态出发,经过若干次状态转移,达到某个终止状态的路径,使得最终的结

    2024年02月22日
    浏览(40)
  • 算法沉淀 —— 动态规划篇(简单多状态dp问题下)

    几乎所有的动态规划问题大致可分为以下5个步骤,后续所有问题分析都将基于此 1.、状态表示:通常状态表示分为基本分为以下两种,其中更是以第一种为甚。 以i为结尾 ,dp[i] 表示什么,通常为代求问题(具体依题目而定) 以i为开始 ,dp[i]表示什么,通常为代求问题(具

    2024年04月16日
    浏览(46)
  • 【算法优选】 动态规划之简单多状态dp问题——贰

    动态规划相关题目都可以参考以下五个步骤进行解答: 状态表示 状态转移⽅程 初始化 填表顺序 返回值 后面题的解答思路也将按照这五个步骤进行讲解。 给定一个整数数组prices,其中第 prices[i] 表示第 i 天的股票价格 设计一个算法计算出最大利润。在满足以下约束条件下,

    2024年04月12日
    浏览(35)
  • 算法沉淀 —— 动态规划篇(简单多状态dp问题上)

    几乎所有的动态规划问题大致可分为以下5个步骤,后续所有问题分析都将基于此 1.、状态表示:通常状态表示分为以下两种,其中更是第一种为主。 以i为结尾 ,dp[i] 表示什么,通常为代求问题(具体依题目而定) 以i为开始 ,dp[i]表示什么,通常为代求问题(具体依题目而

    2024年04月11日
    浏览(43)
  • 动态规划入门:斐波那契数列模型以及多状态(C++)

        动态规划(Dynamic programming,简称 DP)是一种解决多阶段决策问题的算法思想。它将问题分解为多个阶段,并通过保存中间结果来避免重复计算,从而提高效率。 动态规划的解题步骤一般分为以下几步: 思考状态表示,创建dp表(重点) 分析出状态转移方程(重点) 初始化 确定

    2024年02月11日
    浏览(42)
  • 【算法】力扣【动态规划、状态机】309. 买卖股票的最佳时机含冷冻期

    309. 买卖股票的最佳时机含冷冻期 本文介绍解决力扣平台上第309号问题——“买卖股票的最佳时机含冷冻期”的算法。这是一个中等难度的问题,其核心是通过设计一个算法来计算在给定的股票价格数组 prices 下,能够获取的最大利润。股票价格数组 prices 中的每个元素 pric

    2024年01月18日
    浏览(48)
  • acwing算法基础之动态规划--数位统计DP、状态压缩DP、树形DP和记忆化搜索

    暂无。。。 暂无。。。 题目1 :求a~b中数字0、数字1、…、数字9出现的次数。 思路:先计算1~a中每位数字出现的次数,然后计算1~b-1中每位数字出现的次数,两个相减即是最终答案。 那么,如何计算1~a中每位数字出现的次数呢? 首先,将a的每一位存入向量num中,例如a=123

    2024年02月04日
    浏览(49)
  • 【算法学习】斐波那契数列模型-动态规划

            我在算法学习过程中,针对斐波那契数列模型的动态规划的例题进行了一个整理,并且根据标准且可靠一点的动态规划解题思路进行求解类似的动归问题,来达到学习和今后复习的必要。         所谓的斐波那契数列模型,即当前状态的值等于前两种状态的值之和。

    2024年02月04日
    浏览(54)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包