思路: 动态规划
时间复杂度:
O
(
M
L
)
O(ML)
O(ML)
状态转移方程的求解
设fvrt数组记录颜色序列;strp数组记录纸袋颜色;dp[i]表示以i为结尾的最大长度。
基于此,可对每一个fvrt[j]进行遍历,求得当前的状态转移方程为
d
p
[
i
]
=
{
d
p
[
i
−
1
]
+
1
,
if
f
v
r
t
[
j
]
=
s
t
r
p
[
i
]
m
a
x
{
d
p
[
i
−
1
]
,
d
p
[
i
]
}
,
if
f
v
r
t
[
j
]
≠
s
t
r
p
[
i
]
dp[i]= \begin{cases} dp[i-1]+1, & \text {if $fvrt[j] = strp[i]$} \\ max\{dp[i-1],dp[i]\}, & \text{if $fvrt[j] \neq strp[i]$} \end{cases}
dp[i]={dp[i−1]+1,max{dp[i−1],dp[i]},if fvrt[j]=strp[i]if fvrt[j]=strp[i]
d
p
[
0
]
=
0
(sentinel node)
dp[0]=0\text{(sentinel node)}
dp[0]=0(sentinel node)
#include <bits/stdc++.h>
using namespace std;
int fvrt[210];
int strp[10010];
int dp[10010];
int main(void)
{
int N,M,L,cnt=0;
scanf("%d%d",&N,&M);
for(int i=1;i<=M;i++)
scanf("%d",&fvrt[i]);
scanf("%d",&L);
for(int i=1;i<=L;i++)
scanf("%d",&strp[i]);
dp[0]=0; //sentinel node
for(int i=1;i<=L;i++) //initially
{
if(strp[i]==fvrt[1]) cnt++;
dp[i]=cnt;
}
for(int i=2;i<=M;i++)
{
for(int j=1;j<=L;j++)
{
if(fvrt[i]!=strp[j])
dp[j]=max(dp[j-1],dp[j]);
else
dp[j]=dp[j-1]+1;
}
}
printf("%d",dp[L]);
}