3.19 动态规划专题【上】(参考《算法笔记》)

1.最大连续子序列和

给定一个数字序列:A1,A2······An,求i,j(1<=i<=j<=n)使得Ai+······+Aj最大,输出这个最大和。

Sample Input

6

-2 11 -4 13 -5 -2

Sample Output

20

用dp[i]表示从A1到Ai最大连续子序列和,必须是以Ai为结尾的,也就是必须加上Ai。

因为是要连续的序列,所以只有两种可能,第一种就是他本身,第二种就是dp[i-1]+Ai。所以dp[i]就是前面两种的最大值。

#include
#include
#define MAXN 100000
using namespace std;
int dp[MAXN],i,n,num[MAXN];
int main()
{
    while(scanf("%d",&n)!=EOF)
    {
        for(i=1;i<=n;i++)
            scanf("%d",&num[i]);
        dp[1]=num[1];
        for(i=2;i<=n;i++)
            dp[i]=max(dp[i-1]+num[i],num[i]);
        int res=dp[1];
        for(i=2;i<=n;i++)
            res=max(res,dp[i]);
        printf("%d\n",res);
    }
    return 0;
}

2.最长不下降子序列

在一个数字序列中,找到一个最长的子序列(可以不连续)使得这个子序列是不下降(非递减)的。

Sample Input

7

1 2 3 -1 -2 7 9

Sample Output

5

dp[i]表示到以第i个数为结尾的最大子序列的个数。

而dp[i]的计算需要一个循环,从1到i-1的一个循环

循环为i-1时,如果num[i]>=num[i-1]的话,dp[i]=dp[i-1]+1,如果num[i]

如此进行1到i-1循环,其中最大值就是dp[i]的值。

#include
#include
using namespace std;
#define MAX 100000
int dp[MAX],num[MAX],i,j,n;
int main()
{
    while(scanf("%d",&n)!=EOF)
    {
        for(i=1;i<=n;i++)
            scanf("%d",&num[i]);
        int res=-1;
        for(i=1;i<=n;i++)
        {
            dp[i]=1;
            for(j=1;j=num[j])
                    dp[i]=max(dp[i],dp[j]+1);
            }
            res=max(dp[i],res);
        }
        printf("%d\n",res);
    }
    return 0;
}

3.最长公共子序列

给定两个字符串(或数字序列)A和B,求一个字符串,使得这个字符串是A和B最长的公共部分(子序列可以不连续)。

比如 sadstory 跟 adminsorry 最长公共子序列就是 “adsory”

用dp[i][j]表示第一个字符串的第i个字符为止与第二个字符串第j个字符为止最长公共子序列的个数。

如果a[i]==b[j],那么dp[i][j]=dp[i-1][j-1]+1,如果不相等的话,就等于max(dp[i-1][j],dp[i][j-1]).

 

#include
#include
#include
using namespace std;
#define MAX 10000
char a[MAX],b[MAX];
int dp[MAX][MAX],i,j;
int main()
{
    while(gets(a+1)!=NULL)
    {
        gets(b+1);
        int l1=strlen(a+1);
        int l2=strlen(b+1);
        for(i=0;i<=l1;i++)
            dp[i][0]=0;
        for(i=0;i<=l2;i++)
            dp[0][i]=0;
        for(i=1;i<=l1;i++)
        {
            for(j=1;j<=l2;j++)
            {
                if(a[i]==b[j])
                    dp[i][j]=dp[i-1][j-1]+1;
                else
                    dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
            }
        }
        printf("%d\n",dp[l1][l2]);
    }
    return 0;
}

 

你可能感兴趣的:(动态规划)