算法提高之最长公共上升子序列

本文介绍了如何使用线性动态规划解决最长公共上升子序列问题,通过f[i][j]状态表示,详细解释了状态转移方程,包括a[i]不等于b[j]和a[i]等于b[j]两种情况。
摘要由CSDN通过智能技术生成

算法提高之最长公共上升子序列

  • 核心思想:线性dp

    • 最长上升子序列 + 最长公共子序列 融合
    • 状态表示:f[i][j]表示考虑 a 中前 i 个数字,b 中前 j 个数字 ,且当前以 b[j] 结尾的子序列的方案数
    • 状态转移:当前a[i] != b[j] , f[i][j] = f[i-1][j]
      • 当前a[i] == b[j] , f[i][j] = max(f[i][j],f[i-1][k]+1) 其中**k为j左侧的b[k]<b[j]**的元素
  •   #include <iostream>
      
      using namespace std;
      
      const int N = 3010;
      
      int n;
      int a[N], b[N];
      int f[N][N];
      
      int main()
      {
          //input
          cin >> n;
          for (int i = 1; i <= n; ++ i) cin >> a[i];
          for (int i = 1; i <= n; ++ i) cin >> b[i];
          
          for (int i = 1; i <= n; ++ i)
          {
              int maxv = 1;  //用maxv存最大的f[i-1][k]
              for(int j=1;j<=n;j++)
              {
                  f[i][j] = f[i-1][j];
                  if(a[i] == b[j]) f[i][j] = max(f[i][j] , maxv);
                  if(a[i] > b[j]) maxv = max(maxv , f[i-1][j] + 1);
              }
          }
          int res = 0;
          for (int i = 0; i <= n; ++ i) res = max(res, f[n][i]);
          cout << res << endl;
      }
    

参考题解:https://www.acwing.com/solution/content/52304/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阳光男孩01

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值