2023蓝桥杯B组省赛 接龙序列

在这里插入图片描述

 大致思路:应该属于线性DP,子序列问题,通常是去找最xx的一个最值序列(通常是最长)。

序列分为连续或者不连续,连续的有 求连续区间最大和等等,本题为不连续

通常将状态定义为dp[i]以arr[i]结尾的最长子序列这样通常是搭建子问题与原问题的桥梁

本题求去最少多少数能成为接龙序列,其实就是求最长接龙子序列

状态转移方程为

从1-i (k为迭代变量)如果能拼接上 dp[j]=max{dp[j],dp[k] + 1 };

最后得dp[n];

初始化的dp[]={1}

代码如下:

#include 
#include 
#include 
  
using namespace std;
int l[100010],r[100010],dp[100010];
int main()
{
    int n;
    cin>>n;
    for(int i=0;i>s;
        l[i]=s[0]-'0',r[i]=s[s.size()-1]-'0';
    }
     
    int res=0;
    for(int i=0;i

这种复杂度是O(n^2)

当然还有另一种办法:由于接龙数列种类比较少并且由于接龙数列的特殊性

对于第i个值来说不可以不找i之前的可以直接与他匹配的因为只有一个并且总共只有10种类型(用G[N]里面存的是以i为结尾的最大值)因此可以直接通过索引去找,优化时间。

代码如下:

#include 
#include 
#include 
 
using namespace std;
 int g[10];//可以认识是接龙数列的种类只有10种 0,1,2,3,4,5,6,7,8,9
//存储的是以i为结尾的最大子序列长度
int main()
{
    int res=0;
    int n;
    cin>>n;
    for(int i=0;i>s;
       int l=s[0]-'0',r=s[s.size()-1]-'0';
       int f=max(1,g[l]+1);//求接上数列后于不接数列的最大值,
并且因为只有一种所以直接按照索引就能找个从而优化时间复杂度
       g[r]=max(g[r],f);//更新或者不更新
       res=max(res,f);//最终最大值的持续更新
    }
  
   
    cout<

你可能感兴趣的:(c++,动态规划,蓝桥杯)