今天也是斗胆来说一说dp吧
这个最长公共子序列正可谓是经典了
首先说一下什么是子序列:
就是你从一个数列里面随便选几个相邻或不相邻的数,这些数的集合被称为这数列的子序列。
最长公共子序列即两个序列中都包含的序列中最长的那一个
这肯定是dp
废话不多说,方程:
其中后一个max要建立在a[i]=b[j]的情况下。
我们设dp[i][j]表示a的前i个元素与b前j个元素所构成的最长公共子序列
对于dp[i][j]
只有两种情况
1、a[i]和b[j]不一样,那么dp[i][j]就等于前两种状态
要么i-1
要么j-1
i和j同时减那是肯定不行的(废话)
i-1相对于i是最优的,j-1相对于j也肯定是最优的。
2、如果它俩一样,那么就考虑dp[i][j]和前一种状态+1谁更大
前一种状态即dp[i-1][j-1]。
这种dp复杂度为n的平方,
其优化方式。。。额,我也不会
贴上n<=1000的代码
#include<iostream>
using namespace std;
int a[1001], b[1001],dp[1001][1001];
int main() {
int n;
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++)
for (int j = 1; j <= n; j++) {
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
if (a[i] == b[j])dp[i][j] = max(dp[i][j], dp[i - 1][j - 1] + 1);
}
cout << dp[n][n];
}
有些潦草,考完试再说吧
--end--