序列动态规划问题

本文详细解析了四个经典的动态规划问题:最长公共子串、最长递增子序列、最大连续子序列之和以及查找最长连续数字串。通过具体示例和代码实现帮助读者理解动态规划算法的设计思想。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、最长公共字串

#include <iostream>
#include <cstring>
#define MAX_LEN 100


using namespace std;

void max_substr(char *s1, char *s2)
{
    int len1 = strlen(s1), len2 = strlen(s2);
    int r[len1][len2];
    int max_len=0, i, j, loc_i=0, loc_j=0;
    for(i=0; i<len2; ++i)
        r[0][i] = s1[0]==s2[i]?1:0;
    for(i=0; i<len1; ++i)
        r[i][0] = s1[i]==s2[0]?1:0;

    for(i=1; i<len1; ++i)
    {
        for(j=1; j<len2; ++j)
        {
            if(s1[i]==s2[j])
            {
                r[i][j] = r[i-1][j-1]+1;
                if(r[i][j] > max_len)
                {
                    max_len = r[i][j];
                    loc_i=i;
                    loc_j=j;
                }
            }
            else
            {
                r[i][j] = 0;
            }
        }
    }
    cout<<"最大长度为:"<<max_len<<endl;

    for(i=loc_i-max_len+1; i<=loc_i; ++i)
        cout<<s1[i]<<" ";
}


int main()
{
    char s1[MAX_LEN];
    char s2[MAX_LEN];
    cin>>s1;
    cin>>s2;
    max_substr(s1, s2);
}

2、最长上升子序列

import java.util.Scanner;

public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        while(sc.hasNext()){
            int n = sc.nextInt();
            int arr[] = new int[n];
            int dp[] = new int[n];
            for(int i=0; i<n; ++i){
                arr[i] = sc.nextInt();
                dp[i] = 1;
            }
            int res=0;

            for(int i=0; i<n; ++i){
                for(int j=0; j<i; ++j){
                    if(arr[j] < arr[i] ){
                        dp[i] = Math.max(dp[i], dp[j]+1);
                    }
                }
                res = res>dp[i]?res:dp[i];
            }
            System.out.println(res);
        }
    }
}

3、最大连续子序列之和
状态方程:sum[i] = max{sum[i-1]+a[i],a[i]} sum[i]表示以a[i]结尾的连续子序列的最大和

import java.util.Scanner;

public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        while(sc.hasNext()){
            int n = sc.nextInt();
            int[] arr = new int[n];
            for(int i=0; i<n; ++i){
                arr[i] = sc.nextInt();
            }
            int sum=0, max=-999999999;
            for(int i=0; i<n; ++i){
                //sum = Math.max(arr[i], sum+arr[i]);
                //max = Math.max(max, sum);
                sum = sum+arr[i];
                if(sum>max){
                    max = sum;
                }
                if(sum<0) {
                    sum = 0;
                }
            }
            System.out.println(max);
        }
    }
}

4、在字符串中找出连续最长的数字串

import java.util.Scanner;
public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        while(sc.hasNext()){
            String sin = sc.nextLine();
            String sout = "";
            int n = sin.length();
            if(n==0){
                System.out.println("");
                return;
            }
            int[] dp = new int[n];
            if(sin.charAt(0)>='0' && sin.charAt(0)<='9')
                dp[0] = 1;
            for(int i=1; i<n; ++i){
                if(sin.charAt(i)>='0' && sin.charAt(i)<='9'){
                    dp[i] = dp[i-1]+1;
                }else{
                    dp[i] = 0;
                }
            }
            int max = 0;
            for(int i=0; i<n; i++)
                if(dp[i]>max)
                    max = dp[i];
            for(int i=0; i<n; i++){
                if(dp[i]==max){
                    sout += sin.substring(i-max+1, i+1);
                }
            }
            sout += ","+max;
            System.out.println(sout);
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值