UVA 10405【LCS】【背包】

本文介绍了一种解决最长公共子序列(LCS)问题的动态规划方法。通过建立f[i][j]状态表示两个字符串分别到第i和第j位置的LCS长度,利用字符匹配和不匹配两种情况更新状态。代码实现中注意处理空格,并提供了对边界条件的处理。博主分享了代码实现过程,强调了理解动态规划状态转移的重要性,并建议进行多组测试以确保正确性。
摘要由CSDN通过智能技术生成

本题为 LCS 裸题,请求评橙。

考虑 DP。

状态 f [ i ] [ j ] f[i][j] f[i][j] 为第一个字符串选到了 i i i,第二个字符串选到了 j j j(位置)。

容易发现,如果第一个字符串 i i i 位置的字符和第二个字符串 j j j 位置的字符一样,那么有 f [ i ] [ j ] = f [ i − 1 ] [ j − 1 ] + 1 f[i][j] = f[i - 1][j - 1] + 1 f[i][j]=f[i1][j1]+1,否则有 f [ i ] [ j ] = max ⁡ ( f [ i − 1 ] [ j ] , f [ i ] [ j − 1 ] ) f[i][j] = \max(f[i - 1][j], f[i][j - 1]) f[i][j]=max(f[i1][j],f[i][j1])

时间复杂度 O ( n 2 ) O(n^2) O(n2)

实际上有时间复杂度更好的 O ( n log ⁡ n ) O(n\log n) O(nlogn) 算法,但是超纲没写。

坑点:有空格,需要使用 getline 读入。

// 这回只花了45min就打完了。
// 真好。记得多手造几组。最好有暴力对拍。

#include <bits/stdc++.h>

using namespace std;

int f[2010][2010];

int main()
{
  string s, t;
  while (getline(cin, s), getline(cin, t)) // debug 有可能有空格
  {
    if (cin.eof())
      break;
    int l1 = s.size(), l2 = t.size();
    s = ' ' + s, t = ' ' + t;
    for (int i = 1; i <= l1; i ++)
      for (int j = 1; j <= l2; j ++)
        if (s[i] != t[j])
          f[i][j] = max(f[i - 1][j], f[i][j - 1]);
        else
          f[i][j] = f[i - 1][j - 1] + 1;
    cout << f[l1][l2] << '\n';
  }
  return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值