PAT1 1045 Favorite Color Stripe

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/LSC_333/article/details/91040921

题目链接
我的github

题目大意

给两个序列,求两个序列的最大公共子序列(序列中的元素可重复)的长度
例如 {2 2 4 1 5 5 6 3 1 1 5 6}和 {2 3 1 5 6}的最大公共子序列(元素可重复)是{2 2 1 1 1 5 6}, {2 2 1 5 5 5 6}, {2 2 1 5 5 6 6}和 {2 2 3 1 1 5 6}

输入

第一行给一个正整数 N 200 N\leq200 表示序列中的值的范围( 1 1 ~ N N
第二行,第一个数是正整数 M 200 M\leq200 ,表示第一个序列的长度,接着给出 M M 个数
第三行,第一个数是正整数 L 1 0 4 L\leq10^4 ,表示第二个序列的长度,接着给出 L L 个数

输出

对每个例子,在一行中输出最大公共子序列(元素可重复)的长度

样例输入

6
5 2 3 1 5 6
12 2 2 4 1 5 5 6 3 1 1 5 6

样例输出

7

解析

这题和LCS(最大公共子序列)很像,但是不同的一点是元素可重复。
其实修改LCS的状态转移方程式就可以解决元素重复的情况,ans[i][j]表示第一个序列的前i个和第二个序列的前j个的最大公共子序列(元素可重复)的长度,则状态转移方程式:

ans[i][j] = max(ans[i - 1][j], ans[i][j - 1]) if a[i] != b[j] else max(ans[i - 1][j], ans[i][j - 1]) + 1

但是这题用python写叕叒双又超时,用C++就可以AC
python:

# -*- coding: utf-8 -*- 
# @Time : 2019/6/6 10:13 
# @Author : ValarMorghulis 
# @File : 1045.py
def solve():
    n = int(input())
    a = list(map(int, input().split()))
    b = list(map(int, input().split()))
    ans = [[0 for i in range(b[0] + 5)] for j in range(a[0] + 5)]
    for i in range(1, a[0] + 1):
        for j in range(1, b[0] + 1):
            ans[i][j] = max(ans[i - 1][j], ans[i][j - 1]) if a[i] != b[j] else max(ans[i - 1][j], ans[i][j - 1]) + 1
    print(ans[a[0]][b[0]])


if __name__ == "__main__":
    solve()

C++:

#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#include<cstring>
#include<string>
#include<cmath>

#define inf 0xffffffff

using namespace std;


int main()
{
    int n, m, l;
    scanf("%d", &n);
    scanf("%d", &m);
    int a[m+5];
    memset(a, 0, sizeof(a));
    for(int i=1; i<=m; i++)
        scanf("%d", &a[i]);
    scanf("%d", &l);
    int b[l+5];
    memset(b, 0, sizeof(b));
    for(int i=1; i<=l; i++)
        scanf("%d", &b[i]);
    int ans[m+5][l+5];
    memset(ans, 0, sizeof(ans));
    for(int i=1; i<=m; i++)
        for(int j=1; j<=l; j++)
            ans[i][j]=(a[i]==b[j]?max(ans[i][j-1], ans[i-1][j])+1:max(ans[i][j-1], ans[i-1][j]));
    printf("%d\n", ans[m][l]);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/LSC_333/article/details/91040921
今日推荐