DP(状态机模型)

状态机模型01背包问题区别就在于,01背包中每个物品选或不选都是独立的, 不受前者约束不对后者产生影响,而状态机不一样。换成01那种状态之间的转化图来看的话,01背包中0和1的转化不受任何约束,可以说是有向完全图;但是状态机不一样,由于某些条件下的边不存在,于是我们在 计算本次状态之前就可能需要了解前一次的状态,于是需要状态细分标记

大盗阿福

阿福是一名经验丰富的大盗。趁着月黑风高,阿福打算今晚洗劫一条街上的店铺。

这条街上一共有 N 家店铺,每家店中都有一些现金。

阿福事先调查得知,只有当他同时洗劫了两家相邻的店铺时,街上的报警系统才会启动,然后警察就会蜂拥而至。

作为一向谨慎作案的大盗,阿福不愿意冒着被警察追捕的风险行窃。

他想知道,在不惊动警察的情况下,他今晚最多可以得到多少现金?

输入格式

输入的第一行是一个整数 T,表示一共有 T 组数据。

接下来的每组数据,第一行是一个整数 N ,表示一共有 N 家店铺。

第二行是 N 个被空格分开的正整数,表示每一家店铺中的现金数量。

每家店铺中的现金数量均不超过1000。

输出格式

对于每组数据,输出一行。

该行包含一个整数,表示阿福在不惊动警察的情况下可以得到的现金数量。

数据范围

1≤T≤50
1≤N≤10^5

输入样例:

2
3
1 8 2
4
10 7 6 14

输出样例:

8
24

样例解释

对于第一组样例,阿福选择第2家店铺行窃,获得的现金数量为8。

对于第二组样例,阿福选择第1和4家店铺行窃,获得的现金数量为10+14=24。

 线性DP

#include<iostream>
using namespace std;
const int N=1e5+10;
int f[N];
int w[N];
int main()
{
    int t;scanf("%d",&t);
    while(t--)
    {
        int n;scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d",&w[i]);
        for(int i=1;i<=n;i++)
        {
            f[i]=max(f[i-1],f[i-2]+w[i]);
        }
        cout<<f[n]<<endl;
    }
    return 0;
}

 状态机的写法

#include<iostream>
using namespace std;
const int N=1e5+10,INF=1e9;
int f[N][2];
int w[N];
int main()
{
    int t;scanf("%d",&t);
    while(t--)
    {
        int n;scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d",&w[i]);
        f[0][0]=0,f[0][1]=-INF;//f[0][1]=0也可 f[0][0]与f[0][1]相当于入口 入口肯定接到f[1][0]上肯定接到0 上
        for(int i=1;i<=n;i++)
        {
            f[i][0]=max(f[i-1][0],f[i-1][1]);
            f[i][1]=f[i-1][0]+w[i];
        }
        printf("%d\n",max(f[n][0],f[n][1]));
    }
    return 0;
    
}

股票买卖 IV  

给定一个长度为 N 的数组,数组中的第 i 个数字表示一个给定股票在第 i 天的价格。

设计一个算法来计算你所能获取的最大利润,你最多可以完成 k 笔交易。

注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。一次买入卖出合为一笔交易。

输入格式

第一行包含整数 N 和 k,表示数组的长度以及你可以完成的最大交易笔数。

第二行包含 N 个不超过 10000 的正整数,表示完整的数组。

输出格式

输出一个整数,表示最大利润。

数据范围

1≤N≤10^5
1≤k≤100

输入样例1:

3 2
2 4 1

输出样例1:

2

输入样例2:

6 2
3 2 6 5 0 3

输出样例2:

7

样例解释

样例1:在第 1 天 (股票价格 = 2) 的时候买入,在第 2 天 (股票价格 = 4) 的时候卖出,这笔交易所能获得利润 = 4-2 = 2 。

样例2:在第 2 天 (股票价格 = 2) 的时候买入,在第 3 天 (股票价格 = 6) 的时候卖出, 这笔交易所能获得利润 = 6-2 = 4 。随后,在第 5 天 (股票价格 = 0) 的时候买入,在第 6 天 (股票价格 = 3) 的时候卖出, 这笔交易所能获得利润 = 3-0 = 3 。共计利润 4+3 = 7.

#include<iostream>
#include<cstring>
using namespace std;
const int N=1e5+10,M=110;
int f[N][M][2];//f[i][j][k]表示在前i天的股票中,第i天的决策是k,完成的交易数为j的最大利润
int w[N];
int main()
{
    int n,k;cin>>n>>k;
    for(int i=1;i<=n;i++) cin>>w[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=0;j<=k;j++)
        {
            f[i][j][0]=f[i-1][j][0];//0->0(空仓 还是j决策)
           //1 -> 0 (卖出) 买入到卖出都是一次决策 故决策还是j
            if(j) f[i][j][0]=max(f[i][j][0],f[i-1][j][1]+w[i]);// 1 - > 0 
            //1 ->  1(持仓) 0 - >1(买入) 在上一次空仓的基础上买入是一场决策是j-1  这一次是j
            f[i][j][1]=max(f[i-1][j][1],f[i-1][j-1][0]-w[i]);
            
        }
    }
    int res=0;
    for(int j=0;j<=k;j++)
    {
        res=max(res,f[n][j][0]);
    }
    cout<<res<<endl;
    return 0;
}

股票买卖 V  

给定一个长度为 N 的数组,数组中的第 i 个数字表示一个给定股票在第 i 天的价格。

设计一个算法计算出最大利润。在满足以下约束条件下,你可以尽可能地完成更多的交易(多次买卖一支股票):

  • 你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
  • 卖出股票后,你无法在第二天买入股票 (即冷冻期为 1 天)。

输入格式

第一行包含整数 N,表示数组长度。

第二行包含 N 个不超过 10000 的正整数,表示完整的数组。

输出格式

输出一个整数,表示最大利润。

数据范围

1≤N≤10^5

输入样例:

5
1 2 3 0 2

输出样例:

3

样例解释

对应的交易状态为: [买入, 卖出, 冷冻期, 买入, 卖出],第一笔交易可得利润 2-1 = 1,第二笔交易可得利润 2-0 = 2,共得利润 1+2 = 3。

 

 

#include<iostream>
#include<cstring>
using namespace std;
const int N=1e5+10,INF=1e9;
int w[N];
int f[N][3];//f[i][k]表示前i的股票 状态k中 最大价值
int main()
{
   int n;cin>>n;
   for(int i=1;i<=n;i++) cin>>w[i];
    //这样初始化 是因为入口是在状态2里 另外两状态无效 将其弄成负的防止更新别的f[i][j]
    f[0][0]=-INF;
    f[0][1]=-INF;
    f[0][2]=0;
    for(int i=1;i<=n;i++)
    {
      f[i][0] = max(f[i - 1][0], f[i - 1][2] - w[i]);
      f[i][1] = f[i - 1][0] + w[i];
      f[i][2] = max(f[i - 1][2], f[i - 1][1]);
    }
//有可能是一只下降的股票 然后就没有利益0 是f[n][2]一直不买了 这时不是f[n][1] 出口时俩
    cout<<max(f[n][1],f[n][2])<<endl;
    return 0;
}

 

 设计密码

难 用到了KMP 暂时还没有解决

你现在需要设计一个密码 S,S 需要满足:

  • S 的长度是 N;
  • S 只包含小写英文字母;
  • S 不包含子串 T;

例如:abc 和 abcde 是 abcde的子串,abd 不是 abcde 的子串。

请问共有多少种不同的密码满足要求?

由于答案会非常大,请输出答案模 10^9+7 的余数。

输入格式

第一行输入整数N,表示密码的长度。

第二行输入字符串T,T中只包含小写字母。

输出格式

输出一个正整数,表示总方案数模 10^9+7 后的结果。

数据范围

1≤N≤50
1≤|T|≤N,|T|是T的长度。

输入样例1:

2
a

输出样例1:

625

输入样例2:

4
cbc

输出样例2:

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

using namespace std;

const int N=55,mod=1e9+7;

int f[N][N],ne[N];
char str[N];//子串

int main()
{
    int n,m;
    cin>>n>>str+1;
    m=strlen(str+1);

    for(int i=2,j=0;i<=m;i++)//求出ne数组(kmp模板)
    {
        while(j&&str[j+1]!=str[i]) j=ne[j];
        if(str[j+1]==str[i]) j++;
        ne[i]=j;
    }

    f[0][0]=1;//已经匹配了0位,且匹配的子串的位置是0时的方案数为1;(初始化)
    for(int i=0;i<n;i++)//枚举密码位
     for(int j=0;j<m;j++)//把第i位密码匹配到的子串位置都枚举一遍
     //j表示第i位密码匹配到的位置,因为不能包含子串,所以不能匹配到m这个位置
      for(char k='a';k<='z';k++)//把第i+1所有可能的字母都枚举一遍
       {
           //匹配过程:寻找当第i+1的位置是k时,并且密码已经生成了第i位,匹配的子串的位置是j时,能跳到哪个位置
           int u=j;
           while(u&&str[u+1]!=k) u=ne[u];
           if(str[u+1]==k) u++;

           if(u<m) f[i+1][u]=(f[i+1][u]+f[i][j])%mod;
           //因为是从f[i][j](i+1的位置为k)跳到f[i+1][u]这个位置,所以f[i+1][u]=f[i+1][u]+f[i][j];
           /*
           注:可能存在重边,因为j不同但ne[j]是相同的,并且k是相同的,所以此时
           f[i][j1]和f[i][j2]跳到的位置是一样的(k相同,ne[j1]=ne[j2])
           */
       }

    int res=0;
    for(int i=0;i<m;i++) res=(res+f[n][i])%mod;
    //将所有的方案数加起来即为总方案数
    printf("%d",res);

    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/66645.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

浅析 C 语言的共用体、枚举和位域

前言 最近在尝试阅读一些系统库的源码&#xff0c;但是其中存在很多让我感到既熟悉又陌生的语法。经过资料查阅&#xff0c;发现是 C 语言中的共用体和位域。于是&#xff0c;趁着课本还没有扔掉&#xff0c;将一些相关的知识点记录在本文。 文章目录 前言共用体 (union)枚举…

理解 Python 的 for 循环

前言 嗨喽&#xff0c;大家好呀~这里是爱看美女的茜茜呐 在本篇博客中&#xff0c;我们将讨论 Python 中 for 循环的原理。 我们将从一组基本例子和它的语法开始&#xff0c;还将讨论与 for 循环关联的 else 代码块的用处。 然后我们将介绍迭代对象、迭代器和迭代器协议&…

Android 14重要更新预览

Android 14重要更新预览 国际化 Android 14 在 Android 13 的基础上进一步扩展了按应用设定语言功能&#xff0c;提供了一些额外的功能&#xff1a; 自动生成应用的 localeConfig&#xff1a;从 Android Studio Giraffe Canary 7 和 AGP 8.1.0-alpha07 开始&#xff0c;您可以…

Java版企业电子招标采购系统源码Spring Cloud + Spring Boot +二次开发+ MybatisPlus + Redis tbms

​ 功能描述 1、门户管理&#xff1a;所有用户可在门户页面查看所有的公告信息及相关的通知信息。主要板块包含&#xff1a;招标公告、非招标公告、系统通知、政策法规。 2、立项管理&#xff1a;企业用户可对需要采购的项目进行立项申请&#xff0c;并提交审批&#xff0c;查…

【人工智能前沿弄潮】—— SAM自动生成物体mask

SAM自动生成物体mask 由于SAM可以高效处理提示&#xff0c;可以通过在图像上抽样大量的提示来生成整个图像的mask。这种方法被用来生成数据集SA-1B。 类SamAutomaticMaskGenerator实现了这个功能。它通过在图像上的网格中对单点输入提示进行抽样&#xff0c;从每个提示中SAM可…

【动态规划刷题 6】 删除并获得点数 粉刷房子

740. 删除并获得点数 给你一个整数数组 nums &#xff0c;你可以对它进行一些操作。 每次操作中&#xff0c;选择任意一个 nums[i] &#xff0c;删除它并获得 nums[i] 的点数。之后&#xff0c;你必须删除 所有 等于 nums[i] - 1 和 nums[i] 1 的元素。 开始你拥有 0 个点数。…

【数据库】Redis可以替代Mysql吗

Redis和Mysql的搭配 Redis可以替代Mysql吗什么是RedisRedis适用的场景以及优点Redis的缺点 什么是MysqlMysql的优点Mysql缺点 总结 Redis可以替代Mysql吗 Redis不能代替MySQL&#xff0c; Redis和MySQL只能是一种互补。 什么是Redis Redis是一种非关系型数据库&#xff0c;也…

【iPhone】手机还有容量,拍视频却提示 iPhone 储存空间已满

文章目录 前言解决方案 结语 前言 今天在用 iPhone 录像的时候突然提醒我 iPhone储存空间已满 你没有足够的储存空间来录制视频” 可我明明还有 20G 的容量 我非常疑惑&#xff0c;因为我之前还剩1个G都能录像&#xff0c;现在20G反而不行了&#xff0c;于是重启了手机&#…

Kali中AWD靶机环境搭建

Kali中AWD靶机环境搭建 1、kali安装docker2、克隆项目&#xff08;400多M&#xff0c;下载会有点久&#xff09;3、进入项目4、下载镜像5、改镜像名6、比赛环境搭建6.1 启动靶机6.2 连接裁判机&#xff0c;启动check脚本6.3 关闭环境命令 7、 靶机访问方式7.1 web界面访问7.2 s…

代理模式:静态代理+JDK/CGLIB 动态代理

文章目录 1. 代理模式2. 静态代理3. 动态代理3.1. JDK 动态代理机制3.1.1. 介绍 3.1.2. JDK 动态代理类使用步骤3.1.3. 代码示例3.2. CGLIB 动态代理机制3.2.1. 介绍3.2.2. CGLIB 动态代理类使用步骤3.2.3. 代码示例 3.3. JDK 动态代理和 CGLIB 动态代理对比 4. 静态代理和动态…

HTML|计算机网络相关

1.三次握手 第一次握手&#xff1a;客户端首先向服务端发送请求。 第二次握手&#xff1a;服务端在接收到客户端发送的请求之后&#xff0c;需要告诉客户端已收到请求。 第三次握手&#xff1a;客户端在接收到服务端发送的请求和确认信息之后&#xff0c;同样需要告诉服务端已…

【数模】主成分分析PCA

主成分分析(Principal Component Analysis,PCA)&#xff0c;是一种降维算法&#xff0c;它能将多个指标转换为少数几个主成分&#xff0c;这些主成分是原始变量的线性组合&#xff0c;且彼此之间互不相关&#xff0c;其能反映出原始数据的大部分信息。使用场景&#xff1a;一般…

PAT(Advanced Level) Practice(with python)——1023 Have Fun with Numbers

Code N int(input()) D_N 2*N # print(Yes)if len(str(D_N))>len(str(N)):print(No) else:for s in str(D_N):if s not in str(N) or str(D_N).count(s)!str(N).count(s):print("No")breakelse:print(Yes) print(D_N)

【C语言】预处理详解

本文目录 1 预定义符号 2 #define 2.1 #define 定义标识符 2.2 #define 定义宏 2.3 #define 替换规则 2.4 #和## 2.5 带副作用的宏参数 2.6 宏和函数对比 2.7 命名约定 3 #undef 4 命令行定义 5 条件编译 6 文件包含 6.1 头文件被包含的方式 6.2 嵌套文件包含 1 预定义符号 __…

uniapp根据高度表格合并

没有发现比较友好的能够合并表格单元格插件就自己简单写了一个,暂时格式比较固定 一、效果如下 二、UI视图+逻辑代码 <template><view><uni-card :is-shadow="false" is-full

自然语言处理学习笔记(六)————字典树

目录 1.字典树 &#xff08;1&#xff09;为什么引入字典树 &#xff08;2&#xff09;字典树定义 &#xff08;3&#xff09;字典树的节点实现 &#xff08;4&#xff09;字典树的增删改查 DFA&#xff08;确定有穷自动机&#xff09; &#xff08;5&#xff09;优化 1.…

BigDecimal使用总结

BigDecimal Java在java.math包中提供的API类BigDecimal&#xff0c;用来对超过16位有效位的数进行精确的运算。双精度浮点型变量double可以处理16位有效数。 在实际应用中&#xff0c;需要对更大或者更小的数进行运算和处理。float和double只能用来做科学计算或者是工程计算&a…

Leetcode-每日一题【剑指 Offer 06. 从尾到头打印链表】

题目 输入一个链表的头节点&#xff0c;从尾到头反过来返回每个节点的值&#xff08;用数组返回&#xff09;。 示例 1&#xff1a; 输入&#xff1a;head [1,3,2]输出&#xff1a;[2,3,1] 限制&#xff1a; 0 < 链表长度 < 10000 解题思路 1.题目要求我们从尾到头反过…

Python爬虫在电商数据挖掘中的应用

作为一名长期扎根在爬虫行业的专业的技术员&#xff0c;我今天要和大家分享一些有关Python爬虫在电商数据挖掘中的应用与案例分析。在如今数字化的时代&#xff0c;电商数据蕴含着丰富的信息&#xff0c;通过使用爬虫技术&#xff0c;我们可以轻松获取电商网站上的产品信息、用…

401 · 排序矩阵中的从小到大第k个数

链接&#xff1a;LintCode 炼码 - ChatGPT&#xff01;更高效的学习体验&#xff01; 题解&#xff1a; 九章算法 - 帮助更多程序员找到好工作&#xff0c;硅谷顶尖IT企业工程师实时在线授课为你传授面试技巧 class Solution { public:/*** param matrix: a matrix of intege…
最新文章