0
点赞
收藏
分享

微信扫一扫

A1045 Favorite Color Stripe (30 分| 动态规划| LIS| LCS,附详细注释,逻辑分析)


写在前面

  • 思路分析
  • 给出m中颜色作为喜欢色(给出顺序),然后给出1串长度为L的颜色序列,现在要去掉这个序列中不喜欢的颜色,然后求剩下序列的1个子序列,使得这个子序列表示的颜色顺序符合自己喜欢的颜色顺序,不1定所有喜欢颜色都出现。
  • 分析:
  • 喜欢颜色是不重复,把喜欢颜色的序列依次存储到数组中, book[i] = j表示i颜色的下标为j。
  • 先在输入的时候剔除不在喜欢的序列中的元素,然后把剩余的保存在数组a中。
  • 按照最长不下降⼦子列列方式,对于从前到后的每1个i,如果它前面所有的j,1下子找到1个j的下标book[j]比book[i]小,此时就更新dp[i]使它 = max(dp[i], dp[j] + 1);
  • 同时再每1次遍历完成1次j后更新maxn的值为长度最大值,最后输出maxn
  • 新知识点,学习ing

测试用例

input:
6
5 2 3 1 5 6
12 2 2 4 1 5 5 6 3 1 1 5 6
output:
7

ac代码

  • ​​过程详情​​
  • 把输入的喜欢颜色顺序转化成递增顺序排序的1,2,3……N,也就是用一个整数数组a[i]表示颜色标号i的先后顺序。
  • 题目中的2 3 1 5 6 就可以变成 a[2] = 1,a[3] = 2, a[1] = 3,a[5] = 4, a[6] = 5
  • 然后将下面L中颜色转化成喜欢颜色的顺序。用一个vector存储。
  • 题目中的2 2 4 1 5 5 6 3 1 1 5 6变成了颜色序列对应的1 1 0 3 4 4 5 2 3 3 4 5
  • 对于a[i] == 0的颜色,说明这个颜色并非Eva喜欢的颜色。所以不用存储到vector中。
  • vector实际存储的值为1 1 3 4 4 5 2 3 3 4 5
  • 最后按照最长上升子序列对vector中的颜色顺序进行处理

#include <iostream>
#include <vector>
using namespace std;
int book[201], a[10001], dp[10001];
int main()
{
int n, m, x, l, num = 0, maxn = 0;
scanf("%d %d", &n, &m);
for(int i = 1; i <= m; i++)
{
scanf("%d", &x);
book[x] = i;
}
scanf("%d", &l);
for(int i = 0; i < l; i++)
{
scanf("%d", &x);
if(book[x] >= 1)
a[num++] = book[x];
}
for(int i=0; i<num; i++)
{
dp[i] = 1;
for(int j=0; j<i; j++)
if(a[i]>=a[j])
dp[i] = max(dp[i],dp[j]+1);
maxn = max(dp[i], maxn);
}

printf("%d", maxn);
return 0;
}

知识点小结

  • 最长不下降子序列LIS(​​Longest increasing subsequence​​)
  • 最长公共子序列LCS(​​Longest common subsequence​​)
  • A1045 Favorite Color Stripe (30 分| 动态规划| LIS| LCS,附详细注释,逻辑分析)_LIS

  • 公共子串 VS 公共子序列
  • 公共子串: 指连续的公有字符串
  • 公共子序列: 指两个字符串都任意删除0个或多个字符后得到的公有字符串,子序列可以是不连续的
  • 状态转移方程
  • A1045 Favorite Color Stripe (30 分| 动态规划| LIS| LCS,附详细注释,逻辑分析)_动态规划_02

  • A1045 Favorite Color Stripe (30 分| 动态规划| LIS| LCS,附详细注释,逻辑分析)_LIS_03


举报

相关推荐

0 条评论