• 51nod 简单的动态规划


    基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题
     收藏
     关注
    给出两个字符串A B,求A与B的最长公共子序列(子序列不要求是连续的)。
     
    比如两个串为:
     
    abcicba
    abdkscab
     
    ab是两个串的子序列,abc也是,abca也是,其中abca是这两个字符串最长的子序列。
    Input
    第1行:字符串A
    第2行:字符串B
    (A,B的长度 <= 1000)
    Output
    输出最长的子序列,如果有多个,随意输出1个。
    Input示例
    abcicba
    abdkscab
    Output示例
    abca
    状态转移方程为dp[i][j] = a[i]==a[j]?dp[i-1][j-1]+1:max(dp[i-1][j],dp[i][j-1]),然后用dfs搜索回去
    #include <iostream>
    #include <algorithm>
    #include <cmath>
    #include <vector>
    #include <string>
    #include <cstring>
    #pragma warning(disable:4996)
    using namespace std;
    
    char a[1005];
    char b[1005];
    int dp[1005][1005];
    int pre[1005][1005];
    
    void dfs(int m,int n)
    {
        if(m==0||n==0)
            return;
        if(pre[m][n]==1)
        {
            dfs(m-1,n-1);
            cout<<a[m];
        }
        else if(pre[m][n]==2)
        {
            dfs(m-1,n);
        }
        else
        {
            dfs(m,n-1);
        }
    }
    int main()
    {
        int i,j,len1,len2;
        //memset(dp,0,sizeof(dp));
        //memset(pre,0,sizeof(pre));
    
        cin>>a+1>>b+1;
    
        len1=strlen(a+1);
        len2=strlen(b+1);
        
        for(i=1;i<=len1;i++)
        {
            for(j=1;j<=len2;j++)
            {
                if(a[i]==b[j])
                {
                    dp[i][j]=dp[i-1][j-1]+1;
                    pre[i][j]=1;
                }
                else
                {
                    if(dp[i-1][j]>dp[i][j-1])
                    {
                        dp[i][j]=dp[i-1][j];
                        pre[i][j]=2;
                    }
                    else
                    {
                        dp[i][j]=dp[i][j-1];
                        pre[i][j]=3;
                    }
                }
            }
        }
        dfs(len1,len2);
        cout<<endl;
        return 0;
    }
    基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题
     收藏
     取消关注
    给出长度为N的数组,找出这个数组的最长递增子序列。(递增子序列是指,子序列的元素是递增的)
    例如:5 1 6 8 2 4 5 10,最长递增子序列是1 2 4 5 10。
     
    Input
    第1行:1个数N,N为序列的长度(2 <= N <= 50000)
    第2 - N + 1行:每行1个数,对应序列的元素(-10^9 <= S[i] <= 10^9)
    Output
    输出最长递增子序列的长度。
    Input示例
    8
    5
    1
    6
    8
    2
    4
    5
    10
    Output示例
    5
    相关问题
    最长递增子序列 V2 
    160
     
    最长递增子序列的数量 
    160
    思路1:
    dp[i] = MAX(a[j]<a[i])__dp[j])+1 j是0到i内小于a[i]的j,dp[i]是他们最大值加一.但是这样由于每次都要遍历前面的数组导致超时,
    思路二
    在这里引入一个栈,不断向其中插入新的元素,最后取栈顶位置输出纪委最长递增子序列。
    在插入时应当注意,如果插入元素大于栈顶元素,那么继续进栈,否则将元素插入到lower_bound搜索得到的不小于元素键值的下标处并覆盖原键值(这里对最优解不会有影响,因为求的只是长度)。
    网上的代码:
    #include<stdio.h>
    #include<algorithm>
    #include<string.h>
    using namespace std;
    const int maxn = 1E4 * 5 + 10;
    int a[maxn],stk[maxn];
    int main(){
            int n;
            scanf("%d",&n);
            for(int i = 1 ; i <= n ; ++i){
                    scanf("%d",&a[i]);
            }
            int pcur = 0;
            for(int i = 1;i <= n;++i){
                    if(!pcur){
                            stk[pcur++] = a[i];
                    }else {
                            if(a[i] > stk[pcur - 1]){
                                    stk[pcur++] = a[i];
                            }else if(a[i] < stk[pcur - 1]){
                                    int pos = lower_bound(stk,stk + pcur,a[i]) - stk;
                                    stk[pos] = a[i];
                            }
                    }
            }       
            printf("%d
    ",pcur);
            return 0;
    }
    基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题
     收藏
     关注
    在N件物品取出若干件放在容量为W的背包里,每件物品的体积为W1,W2……Wn(Wi为整数),与之相对应的价值为P1,P2……Pn(Pi为整数)。求背包能够容纳的最大价值。
    Input
    第1行,2个整数,N和W中间用空格隔开。N为物品的数量,W为背包的容量。(1 <= N <= 100,1 <= W <= 10000)
    第2 - N + 1行,每行2个整数,Wi和Pi,分别是物品的体积和物品的价值。(1 <= Wi, Pi <= 10000)
    Output
    输出可以容纳的最大价值。
    Input示例
    3 6
    2 5
    3 8
    4 9
    Output示例
    14

    状态转移
    dp[MAXN][10000] 表示前i个物品空间为v的价值
    状态转移的方程有放和不放两种,可得:
    dp[i][m] = max(dp[i-1][m]__不放,dp[i-1][m-w[i]]+v[i])

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int MAXN =101;
    /*
    状态转移
    dp[MAXN][10000] 表示前i个物品空间为v的价值
    状态转移的方程有放和不放两种,可得:
        dp[i][m] = max(dp[i-1][m]__不放,dp[i-1][m-w[i]]+v[i])
    */
    int dp[MAXN][10001];
    int w[MAXN],v[MAXN];
    int main()
    {
        int n,maxw,max_all=-1;
        scanf("%d%d",&n,&maxw);
        for(int i=0;i<n;i++)
        {
            scanf("%d%d",&w[i],&v[i]);
            if(i==0)
            {
                dp[0][w[i]] = v[i];
            }
            else
            {
                for(int k=0;k<=maxw;k++)
                {
                    if(k<w[i])
                        dp[i][k]=dp[i-1][k];//没有空间
                    else
                        dp[i][k] = max(dp[i-1][k],dp[i-1][k-w[i]]+v[i]);
                    max_all=max(max_all,dp[i][k]);
                }    
            }
        }    
        cout<<max_all<<endl;
        return 0;
    基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题
     收藏
     关注
    编辑距离,又称Levenshtein距离(也叫做Edit Distance),是指两个字串之间,由一个转成另一个所需的最少编辑操作次数。许可的编辑操作包括将一个字符替换成另一个字符,插入一个字符,删除一个字符。
    例如将kitten一字转成sitting:
    sitten (k->s)
    sittin (e->i)
    sitting (->g)
    所以kitten和sitting的编辑距离是3。俄罗斯科学家Vladimir Levenshtein在1965年提出这个概念。
    给出两个字符串a,b,求a和b的编辑距离。
     
    Input
    第1行:字符串a(a的长度 <= 1000)。
    第2行:字符串b(b的长度 <= 1000)。
    Output
    输出a和b的编辑距离
    Input示例
    kitten
    sitting
    Output
    3
    在这里删除元素和插入的效果相同可以不用考虑,只考虑替换和插入dp[i][j]表示由a的前i个字符转换到b的前j个字符所需要的步数,插入是
    dp[i][j] = max(dp[i-1][j],dp[i][j-1])+1,
    替换是,dp[i][j] = dp[i-1][j-1],当a[i]==b[j] 不必操作 dp[i][j]=dp[i-1][j-1]
    可得
    dp[i][j] = max(dp[i-1][j]+1,dp[i][j-1]+1,dp[i-1][j-1]+a[i]==b[j]?0:1)

  • 相关阅读:
    在Xampp中添加memache扩展
    使用PHP中的curl发送请求
    php开启openssl扩展
    chisel初见2
    chisel初见
    数字IC设计之DC(二):DC设置、库和对象
    数字IC设计之DC(一):DC简介
    IC基础(八):数字电路设计中常用的算法
    IC基础(七):FPGA为什么与ASIC频率差异巨大?
    IC基础(六):时序分析过程需要的相关计算以及处理方法
  • 原文地址:https://www.cnblogs.com/joeylee97/p/6144194.html
Copyright © 2020-2023  润新知