zoukankan      html  css  js  c++  java
  • 最长子序列问题

    最长上升子序列LCS

        输入n及一个长度为n的数列,求出此序列的最长上升子序列长度。上升子序列指的是对于任意的i<j都满足ai<aj的子序列。(1<=n<=1000,0<=ai<=1000000)
    

    样例输入:

    5

    4 2 3 1 5

    样例输出:

    3(最长上升子序列为2, 3, 5)

    #include<iostream>
    #include<algorithm>
    const int N =1005;
    using namespace std;
    int shu[N];
    int DP[N]; 
    int main(){
    	int m,n;
    	cin>>n;
    	for(int i=1;i<=n;i++){
    		cin>>shu[i];
    		DP[i]=1;//初始化DP距离数组 
    	}
    	int t=0;
    	for(int i=1;i<=n;i++)
    	  {
    		 for(int j=1;j<i;j++){
    		 	if(shu[j]<shu[i]){
    		 		DP[i]=max(DP[i],DP[j]+1);
    			 }
    			 t=max(t,DP[i]);
    		 } 
      	}
    	cout<<t;
    	return 0;
    }
    

    题解:动态规划思想,定义一个数组dp[i]对应输入的数组,dp默认值为1(若数组是从大到小排列的 t为1),判断方法若shu[j]<shu[i]则为上升子序列的一部分所以dp[j]+1与dp[i]比较,找最大值,修改dp[i],结果最后遍历找最大值,当然边查边找最大值也行。
    关于dp[j]+1和dp[i]的状态转换方程,有样例入手,如果出现dp[j]<dp[i],那么dp[i]上不一定会变点的,若dp[i]>dp[j]那么肯定有dp[j]上的最大数量加上dp[i]条件必然也是满足的
    所以说dp[j]+1要和dp[i]进行比较选择最大的作为dp[i]的最大上升子序列数量

    最长公共子序列LCS

    给定两个字符串s1和s2(长度均不超过1000),求出这两个字符串的最长公共子序列的长度。

    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<cstdlib>
    #include<cstdio>
    const int N=10010;
    char s1[N],s2[N];
    int dp[N][N];  //串s1的前i个字符 和 串s2的前j个字符的最长公共子序列长度
    using namespace std;
    int main(){
    	int m,n;
    	int len1,len2;
    	while(scanf("%s",s1)!=EOF){
    		
    		scanf("%s",s2);
    		 len1=strlen(s1);
    		 len2=strlen(s2);
    		 dp[0][0]=0;    //s1,s2都为空时 
    		for(int i=1;i<=len1;i++)dp[i][0]=0;    //s2为空时   输出长度为0 
    		for(int i=1;i<=len2;i++)dp[0][i]=0;     //s1为空时  输出长度为0 
    		
    		for(int i=0;i<len1;i++)        //注意循环的范围
    		 for(int j=0;j<len2;j++){
    		 	if(s2[j]==s1[i]){
    		 		dp[i+1][j+1]=dp[i][j]+1;    //当s1,s2对应的位置字符相等时更新 
    			 }
    			 else{
    			 	dp[i+1][j+1]=max(dp[i][j+1],dp[i+1][j]);//其他情况 
    			 }
    		 }
    		
    		for(int i=1;i<=len1;i++)
            {
                for(int j=1;j<=len2;j++)
                    printf("dp[%d][%d]=%d ",i,j,dp[i][j]);
                printf("
    ");
            }
    	}
         cout<<dp[len1][len2];	
    	return  0;
    } 
    

    注释:设一个二维的数组,dp[i][j]模拟s1....si,s2......sj的最长公共子序列,动态规划的方法解决问题当前状态和下一状态,生成装填转换函数,

    dp[i+1][j+1]=dp[i][j]+1, ①//若出现相等

    max(dp[i][j+1], dp[i+1][j]), ②//否则

    有点小乱等我在思考思考

    最大公共子串LCS

    给定两个字符串s1和s2(长度均不超过1000),求出这两个字符串的最大公共子串的长度。
    这个比上一个简单一些吧第二步的状态转换函数改为0 就行

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    const int maxlen=1010;
    char s1[maxlen],s2[maxlen];
    int dp[maxlen][maxlen];    //dp[i][j]为串s1的前i个字符和串s2的前j个字符的最大公共子串长度
    int main()
    {
        int i,j;
        int len1,len2,ret;     //ret记录结果
        while(scanf("%s",s1)!=EOF)
        {
            scanf("%s",s2);
            memset(dp,0,sizeof(dp));   //初始化:开始LCS长度均为0
            len1=strlen(s1);
            len2=strlen(s2);
            ret=0;
            for(i=0;i<len1;i++)
            {
                for(j=0;j<len2;j++)
                {
                    if(s1[i]==s2[j])
                        dp[i+1][j+1]=dp[i][j]+1;
                    else
                        dp[i+1][j+1]=0;
                    ret=max(ret,dp[i+1][j+1]);    //随时更新最大值
                }
            }
            printf("%d
    ",ret);
        }
        return 0;
    }
    
  • 相关阅读:
    日期获取以及时间转化
    ddt 接口框架数据处理调用excel 处理
    ddt 测试用例UI运用
    动态验证码处理UI自动化获取处理
    Bug Report For .Net (zz.IS2120@BG57IV3)
    中关村翠湖科技园:高端产业聚集区 (zz.IS2120@BG57IV3.T752270541 .K)
    vc6,windows 7 x64 调试 (IS2120@BG57IV3)
    Excel c#Excel文件的操作[转载]
    NUnit学习 标签、方法 记录与说明
    Excel c#Excel工作进程的创建写 与Excel文件的保存[原创] (20100205 11:09)
  • 原文地址:https://www.cnblogs.com/saber114567/p/9350415.html
Copyright © 2011-2022 走看看