【动态规划算法】蓝桥杯填充问题(C/C++)

简介: 【动态规划算法】蓝桥杯填充问题(C/C++)

动态规划(Dynamic Programming,简称DP)是一种在数学、管理科学、计算机科学、经济学和生物信息学等领域中使用的,通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。动态规划常常用于优化那些具有重叠子问题和最优子结构性质的问题。

动态规划的基本步骤:

1. 问题分解:将复杂的原问题分解为若干个相对简单的子问题。

2. 最优子结构:问题的最优解包含其子问题的最优解。

3. 状态定义:描述问题的状态,dp数组定义为几维,代表什么含义。

4. 状态转移方程:找出状态之间的关系,这是动态规划算法的核心,只要有了状态转移方程,那么动态规划就成功了一大半了。

5. 边界条件:确定初始状态或边界条件,一般确定dp[0]/dp[0][0],给一个初始值,还有就是确定它要更新到哪一个状态就完成了。

6. 计算顺序:确定各状态按照什么顺序进行计算,以保证在计算当前状态时,所需要的子状态已被计算。

7. 构造最优解:根据子问题的最优解,构造原问题的最优解。

动态规划的常见问题类型:

动态规划的问题在算法竞赛中非常多,特别是蓝桥杯,几乎每一年都需考,当需要学习蓝桥杯时,建议多去学习学习动态规划问题。在动态规划问题中,有的问题非常简单都是模板题,例如背包问题、LCS、LIS等等,但是也有比较难的题,例如数位DP、DP的优化问题、四边形不等理论等这种难题就需要根据自身量力而行了。比如四边形不等理论这个东西博主连听说过都没有,还是在书上看到的,学习动态规划关键就是多做题积累,去做完题总结,看它的DP是如何定义的,如何状态转移的,下面列举几个常见的DP问题。

1. 背包问题:包括0/1背包、完全背包、多重背包问题等。

2. 最长递增子序列:找出序列中最长的严格递增子序列。

3. 最短路径问题:在加权图中找到两点之间的最短路径。

4. 矩阵链乘问题:计算矩阵序列的乘积,并找出最优的乘法顺序。

5. 硬币找零问题:使用最少的硬币数量来凑成特定的金额。


动态规划是一种非常强大的算法,它的变化性很强,我们要根据题目实际情况进行选择行使用动态规划,定义的状态是什么,表示什么含义,状态如何转移。下面我们以第十四届蓝桥杯省赛大学C组(C/C++)填充这一题为例题,进行讲解动态规划。

原题链接:填充

有一个长度为 n 的 01 串,其中有一些位置标记为 ?,这些位置上可以任意填充 0 或者 1,请问如何填充这些位置使得这个 01 串中出现互不重叠01 子串最多,输出子串个数。

输入格式

输入一行包含一个字符串。

输出格式

输出一行包含一个整数表示答案。

数据范围

对于所有评测用例,1≤n≤10^6。

输入样例:

1110?0

输出样例:

2

样例解释:

如果在问号处填 0,则最多出现一个 00 和一个 11111000


解题思路:

主要利用动态规划思想,定义一个dp[i]表示遍历到第i个位置的最大字串个数。第i个位置可以由前一个位置转移,分下面三种情况:


1.如果当前位置为0,它前一位三种情况0,1,?,当前一位为0或?时可以凑成字串,dp[i]=dp[i-1]+1,否则无法凑成字串dp[i]=dp[i-1]。


2.如果当前位置为1,它前一位三种情况0,1,?,当前一位为1或?时可以凑成字串,dp[i]=dp[i-1]+1,否则无法凑成字串dp[i]=dp[i-1]。


3.如果当前位置为?,它前一位三种情况0,1,?,当前一位为0、1或?时可以凑成字串,dp[i]=dp[i-1]+1,否则无法凑成字串dp[i]=dp[i-1]。


我们每次把能够凑成字串的位置都标记为2,防止重复利用。


代码实现:

#include<iostream>
#include<cstring>
using namespace std;
const int N=1e6+5;
string s;
int res;
int dp[N];
int main(){
  cin>>s;
  for(int i=1;i<s.size();i++){
    if(s[i]=='0'){//第一种情况
      if(s[i-1]=='0'||s[i-1]=='?'){
        dp[i]=dp[i-1]+1;
        s[i]=s[i-1]='2';
      }
      dp[i]=max(dp[i],dp[i-1]);
    }
    if(s[i]=='1'){//第二种情况
      if(s[i-1]=='1'||s[i-1]=='?'){
        dp[i]=dp[i-1]+1;
        s[i]=s[i-1]='2';
      }
      dp[i]=max(dp[i],dp[i-1]);
    }
    if(s[i]=='?'){//第三种情况
      if(s[i-1]=='0'||s[i-1]=='1'||s[i-1]=='?'){
        dp[i]=dp[i-1]+1;
        s[i]=s[i-1]='2';
      }
      dp[i]=max(dp[i],dp[i-1]);
    }
  }
  cout<<dp[s.size()-1]<<endl;
  return 0;
}

DP问题只要能找到状态转移方程就基本解决了,博主感觉最难的还是状态的定义与描述。多做题积累经验,文章代码实现或者思路有错误的地方,请各位大佬指出,感激不尽*~*。


执笔至此,感触彼多,全文将至,落笔为终,感谢大家的支持。

相关文章
|
22天前
|
机器学习/深度学习 存储 算法
动态规划算法深度解析:0-1背包问题
0-1背包问题是经典的组合优化问题,目标是在给定物品重量和价值及背包容量限制下,选取物品使得总价值最大化且每个物品仅能被选一次。该问题通常采用动态规划方法解决,通过构建二维状态表dp[i][j]记录前i个物品在容量j时的最大价值,利用状态转移方程避免重复计算子问题,从而高效求解最优解。
245 1
|
5月前
|
存储 监控 算法
基于 C++ 哈希表算法实现局域网监控电脑屏幕的数据加速机制研究
企业网络安全与办公管理需求日益复杂的学术语境下,局域网监控电脑屏幕作为保障信息安全、规范员工操作的重要手段,已然成为网络安全领域的关键研究对象。其作用类似网络空间中的 “电子眼”,实时捕获每台电脑屏幕上的操作动态。然而,面对海量监控数据,实现高效数据存储与快速检索,已成为提升监控系统性能的核心挑战。本文聚焦于 C++ 语言中的哈希表算法,深入探究其如何成为局域网监控电脑屏幕数据处理的 “加速引擎”,并通过详尽的代码示例,展现其强大功能与应用价值。
116 2
|
7月前
|
存储 负载均衡 算法
基于 C++ 语言的迪杰斯特拉算法在局域网计算机管理中的应用剖析
在局域网计算机管理中,迪杰斯特拉算法用于优化网络路径、分配资源和定位故障节点,确保高效稳定的网络环境。该算法通过计算最短路径,提升数据传输速率与稳定性,实现负载均衡并快速排除故障。C++代码示例展示了其在网络模拟中的应用,为企业信息化建设提供有力支持。
185 15
|
7月前
|
存储 算法 数据处理
公司局域网管理中的哈希表查找优化 C++ 算法探究
在数字化办公环境中,公司局域网管理至关重要。哈希表作为一种高效的数据结构,通过哈希函数将关键值(如IP地址、账号)映射到数组索引,实现快速的插入、删除与查找操作。例如,在员工登录验证和设备信息管理中,哈希表能显著提升效率,避免传统线性查找的低效问题。本文以C++为例,展示了哈希表在局域网管理中的具体应用,包括设备MAC地址与IP分配的存储与查询,并探讨了优化哈希函数和扩容策略,确保网络管理高效准确。
|
3月前
|
存储 监控 算法
基于跳表数据结构的企业局域网监控异常连接实时检测 C++ 算法研究
跳表(Skip List)是一种基于概率的数据结构,适用于企业局域网监控中海量连接记录的高效处理。其通过多层索引机制实现快速查找、插入和删除操作,时间复杂度为 $O(\log n)$,优于链表和平衡树。跳表在异常连接识别、黑名单管理和历史记录溯源等场景中表现出色,具备实现简单、支持范围查询等优势,是企业网络监控中动态数据管理的理想选择。
92 0
|
5月前
|
监控 算法 数据处理
基于 C++ 的 KD 树算法在监控局域网屏幕中的理论剖析与工程实践研究
本文探讨了KD树在局域网屏幕监控中的应用,通过C++实现其构建与查询功能,显著提升多维数据处理效率。KD树作为一种二叉空间划分结构,适用于屏幕图像特征匹配、异常画面检测及数据压缩传输优化等场景。相比传统方法,基于KD树的方案检索效率提升2-3个数量级,但高维数据退化和动态更新等问题仍需进一步研究。未来可通过融合其他数据结构、引入深度学习及开发增量式更新算法等方式优化性能。
148 17
|
4月前
|
机器学习/深度学习 存储 算法
基于 C++ 布隆过滤器算法的局域网上网行为控制:URL 访问过滤的高效实现研究
本文探讨了一种基于布隆过滤器的局域网上网行为控制方法,旨在解决传统黑白名单机制在处理海量URL数据时存储与查询效率低的问题。通过C++实现URL访问过滤功能,实验表明该方法可将内存占用降至传统方案的八分之一,查询速度提升约40%,假阳性率可控。研究为优化企业网络管理提供了新思路,并提出结合机器学习、改进哈希函数及分布式协同等未来优化方向。
95 0
|
6月前
|
存储 监控 算法
基于 C++ 哈希表算法的局域网如何监控电脑技术解析
当代数字化办公与生活环境中,局域网的广泛应用极大地提升了信息交互的效率与便捷性。然而,出于网络安全管理、资源合理分配以及合规性要求等多方面的考量,对局域网内计算机进行有效监控成为一项至关重要的任务。实现局域网内计算机监控,涉及多种数据结构与算法的运用。本文聚焦于 C++ 编程语言中的哈希表算法,深入探讨其在局域网计算机监控场景中的应用,并通过详尽的代码示例进行阐释。
123 4
|
7月前
|
存储 算法 安全
企业员工数据泄露防范策略:基于 C++ 语言的布隆过滤器算法剖析[如何防止员工泄密]
企业运营过程中,防范员工泄密是信息安全领域的核心议题。员工泄密可能致使企业核心数据、商业机密等关键资产的流失,进而给企业造成严重损失。为应对这一挑战,借助恰当的数据结构与算法成为强化信息防护的有效路径。本文专注于 C++ 语言中的布隆过滤器算法,深入探究其在防范员工泄密场景中的应用。
120 8
|
8月前
|
存储 算法 Java
算法系列之动态规划
动态规划(Dynamic Programming,简称DP)是一种用于解决复杂问题的算法设计技术。它通过将问题分解为更小的子问题,并存储这些子问题的解来避免重复计算,从而提高算法的效率。
270 4
算法系列之动态规划