POJ 2533 POJ 1458 HUD 1423 动态规划 LIS LCS LCIS

最长上升子序列
TimeLimit:1000MS MemoryLimit:64MB
64-bit integer IO format:%lld
Problem Description
如果一个数列ai 满足 a1 < a2 < … < aN 则这个数列被称作上升序列。

给定一个数列a(a1, a2, …, aN)则任意一个数列b(ai1, ai2, …, aiK)并且满足(1 <= i1 < i2 < … < iK <= N).则b被称为a的子序列。

如果一个数列的子序列是上升序列,则这个序列称为原序列的上升子序列。

比如序列(1, 7, 3, 5, 9, 4, 8)的上升子序列有(1, 7), (3, 4, 8)等. 它的最长上升子序列长度是4,即(1, 3, 5, 8).

请你写一个程序求一个序列的最长上升子序列的长度。

Input
第一行是一个整数N表示给定数列的长度. 第二行包括N个范围在0~10000的整数。 1 <= N <= 1000

Output
输出一个整数表示最长上升子序列的最大长度

SampleInput
7
1 7 3 5 9 4 8
SampleOutput
4

题意:求最长上升子序列的长度
思路: LIS板子

#include <iostream>
#include <algorithm>

using namespace std;

const int N = 1005;
int a[N],dp[N];

int main()
{
    int n;

    cin >> n;

    for(int i=1;i<=n;i++)
    {
        cin >> a[i];
        dp[i]=1;///最少会有一个元素
    }

    for(int i=2;i<=n;i++)///外层循环记录子问题的答案
    {
        for(int j=1;j<i;j++)///遍历子问题
        {
            if(a[i]>a[j])///如果不满足条件
            {
                dp[i]=max(dp[i],dp[j]+1);///作出决策 在当前阶段和前一阶段中求最大值
            }
        }
    }

    cout << *max_element(dp+1,dp+n+1) << endl;///求出子问题答案的最大值

    return 0;
}

最长公共子序列
TimeLimit:1000MS MemoryLimit:10MB
64-bit integer IO format:%lld
Problem Description
给定两个序列X和Y,求X和Y的最大长度公共子序列的长度。

一个序列的子序列,定义如下,选取一组严格递增的下标<i1,i2,i3,i4,……im>

则这些上标上的元素构成的新序列就是原序列的子序列,

比如序列 X = < a, b, c, f, b, c > ,选取下标 < 1, 2, 4, 6 >.后得到的序列Z=<a,b,f,c>就是X的子序列之一

Input
The program input is from the std input. Each data set in the input contains two strings representing the given sequences. The sequences are separated by any number of white spaces. The input data are correct.

字符串长度小于等于1000

Output
For each set of data the program prints on the standard output the length of the maximum-length common subsequence from the beginning of a separate line.
SampleInput
abcfbc abfcab
programming contest
abcd mnp
SampleOutput
4
2
0
思路:LCS板子

#include <iostream>
#include <algorithm>

using namespace std;

const int N = 1005;

int dp[N][N];

int main()
{
    string s1,s2;

    while(cin >> s1 >> s2)
    {
        for(int i=0;i<=s1.size();i++)///将第一行第一列清零
            dp[i][0]=0;
        for(int i=0;i<=s1.size();i++)
            dp[0][i]=0;

        for(int i=1;i<=s1.size();i++)
        {
            for(int j=1;j<=s2.size();j++)
            {
                if(s1[i-1]==s2[j-1])///如果相等 则这一阶段的答案是上一阶段+1
                    dp[i][j]=dp[i-1][j-1]+1;
                else
                    dp[i][j]=max(dp[i-1][j],dp[i][j-1]);///如果不等  从上一阶段中求出更优秀的解
            }
        }

        cout << dp[s1.size()][s2.size()] << endl;
    }

    return 0;
}

最长公共上升子序列
TimeLimit:1000MS MemoryLimit:32768MB
64-bit integer IO format:%I64d
Problem Description
This is a problem from ZOJ 2432.To make it easyer,you just need output the length of the subsequence.
Input
第一行是一个整数T,代表有T组数据

Each sequence is described with M - its length (1 <= M <= 500) and M integer numbers Ai (-2^31 <= Ai < 2^31) - the sequence itself.

Output
output print L - the length of the greatest common increasing subsequence of both sequences.

注意每两组数据间要留一个空行,最后一组数据后不能有空行

SampleInput
1

5
1 4 2 5 -12
4
-12 1 2 4
SampleOutput
2

LCIS
思路:就是从LCS+LIS的基础上修改

#include <iostream>
#include <algorithm>
#include <cstring>

using namespace std;

const int N = 505;

int a[N],b[N];
int dp[N][N];

void init()
{
    memset(a,0,sizeof(a));
    memset(b,0,sizeof(b));
    memset(dp,0,sizeof(dp));
}

int main()
{
    int t;

    cin >> t;

    while(t--)
    {
        init();

        int n,m;
        int temp=-100000;

        cin >> n;

        for(int i=1;i<=n;i++)
            cin >> a[i];

        cin >> m;

        for(int i=1;i<=m;i++)
            cin >> b[i];

        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                if(a[i]==b[j]&&a[i]>=temp)///两个值相同 并且是递增的则这一阶段答案+1
                {
                    dp[i][j]=dp[i-1][j-1]+1;
                    temp=a[i];
                }
                else
                {
                    dp[i][j]=max(dp[i-1][j],dp[i][j-1]);///否则 从上一阶段找出更优秀的解
                }
            }
        }

        cout << dp[n][m] << endl;
        if(t)
            cout << endl;
    }

    return 0;
}
发布了54 篇原创文章 · 获赞 0 · 访问量 1225

猜你喜欢

转载自blog.csdn.net/weixin_44144278/article/details/99618392
今日推荐