动态规划经典模型整理

版权声明:转载注明出处就好啦~ https://blog.csdn.net/qq_36693533/article/details/78484891

最长上升子序列:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
int n,ans=1;
int sequence[10000],f[10000];
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    scanf("%d",&sequence[i]);
    /*f[1] = 1;
    for(int i=2;i<=n;++i)
    {
        f[i]=1;//到i为止的最长上升子序列长度
        for(int j=1;j<i;++j)
        if(sequence[j]<sequence[i])//“<=”不下降子序列
        f[i]=max(f[i],f[j]+1);
    }
    printf("%d",f[n]);*/
    f[1]=sequence[1];
    for(int i=2;i<=n;i++)
    {
        if(sequence[i]>f[ans])
        f[++ans]=sequence[i];
        else
        {
            /*int l=1,r=ans;
            while(l<r)
            {
                int mid=(l+r+1)/2;
                if (f[mid]<=sequence[i])
                l=mid;
                else
                r=mid-1;
            }
            int j=l;*/
            int j=upper_bound(f+1,f+ans+1,sequence[i])-f;
            f[j]=sequence[i];
        }
    }
    printf("%d",ans);
    return 0;
}

最长公共子序列:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
int f[5000][5000];
char a[10000],b[10000];
int main()
{
    while(~scanf("%s%s",a+1,b+1))
    {
        int len1=strlen(a+1);
        int len2=strlen(b+1);
        f[0][0]=0;//a串匹配到第i位,b串第j位的最长公共子序列长度 
        for(int i=1;i<=len1;i++)
        {
            for(int j=1;j<=len2;j++)
            {
                f[i][j]=max(f[i-1][j],f[i][j-1]);
                if(a[i]==b[j])//注意不要写成a[i]==b[i]
                f[i][j]=max(f[i][j],f[i-1][j-1]+1);
            }
        }
        printf("%d\n",f[len1][len2]);
    }
    return 0;
}

最长公共子串:

Codevs 1425 最长公共子串

取前两个字符串求最长公共子串。
再用公共子串和下一个字符串找公共子串,以此类推。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
const int mod = 100000000;
char a[1000010],b[1000010];
int n,ans,lan,lbn,pos;
int dp[3010][3010];
int main()
{
    scanf("%d",&n);
    scanf("%s",a+1);
    lan=strlen(a+1);
    for(int i=2;i<=n;i++)
    {
        ans=0;
        scanf("%s",b+1);
        lbn=strlen(b+1);
        for(int i=1;i<=lan;i++)
        {
            for(int j=1;j<=lbn;j++)
            {
                if(a[i]==b[j])  
                {
                    dp[i][j]=dp[i-1][j-1]+1;
                    if(dp[i][j]>ans)
                    {
                        ans=dp[i][j];
                        pos=j;
                    }
                }
            }
        }
        memset(a,0,sizeof(a));
        int tmp=ans;
        for(int i=1;i<=ans;i++)
        a[i]=b[pos-tmp+1],tmp--;
        lan=strlen(a+1);
    }
    for(int i=1;i<=ans;i++)
    printf("%c",a[i]);
    return 0;
}

最长公共上升子序列:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
int n,m,maxn,ans;
int a[100000],b[100000],f[5000][5000];
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    scanf("%d",&a[i]);
    //scanf("%d",&m);
    m=n;
    for(int i=1;i<=m;i++)
    scanf("%d",&b[i]);
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            if(a[i]!=b[j])
            f[i][j]=f[i-1][j];
            if(a[i]==b[j])
            {
                maxn=0;
                for(int k=1;k<=j-1;k++)
                {
                    if(b[j]>b[k])
                    maxn=max(maxn,f[i-1][k]);
                }
                f[i][j]=maxn+1;
            }
        }
    }
    for(int i=1;i<=m;i++)
    ans=max(ans,f[n][i]);
    printf("%d",ans);
    return 0;
}

最大子段和:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
int n,ans;
int num[1000010],dp[1000010];//dp[i]以i结尾的最大子段和 
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    scanf("%d",&num[i]);
    for(int i=1;i<=n;i++)
    {
        if(dp[i-1]>0)
        dp[i]=dp[i-1]+num[i];//这样若dp[i]为正数,正确,若为负数,一定不会作为答案不影响正确性 
        else dp[i]=num[i];//前面的负数必然不能使当前值更大 
        if(dp[i]>ans)
        ans=dp[i];
    }
    printf("%d",ans);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_36693533/article/details/78484891
今日推荐