zoukankan      html  css  js  c++  java
  • poj 1458 Common Subsequence(区间dp)

    题目链接:http://poj.org/problem?id=1458

    思路分析:经典的最长公共子序列问题(longest-common-subsequence proble),使用动态规划解题。

    1)问题定义:给定两个序列X=<X1, X2, ...., Xm>和Y = <Y1, Y2, ...., Yn>,要求求出X和Y长度最长的最长公共子序列;

    2)问题分析:

                   <1>动态规划问题都是多阶段决策最优化问题;在这些问题中,问题可以被划分为多个阶段,每个阶段都需要作出一个决策,在问题的多阶段决策中,

                          按某一顺序,根据每一步所选决策的不同,将随即引起状态的转移,最终在变化的状态中产生一个决策序列。动态规划就是为了使产生的决策序列

                         在符合某种条件下达到最优。另外,由于动态规划问题具有最优子结构,所以整体中的最优解一定包含子问题的最优解;

                        如果从图的搜索角度来看,则存在一个状态之间相互连接的有向图,当前状态所做出的每一个可能的决策都或引出一条通向下一状态的边,而且该边具

                        有权重;动态规划问题即为从初始状态寻找一条通往最终的目标状态的最优路径;在寻找最优路径时,由于最优子结构性质可知,在最优路径中,从初

                        始状态到最佳路径中的每一个状态的路径都是最佳路径;所以我们需要先寻找出到入射到目标状态的各个前一状态的最佳路径,即求解子问题的最优解;

                         所以,在该具体的问题中,我们定义序列X=<X1, X2, ..., Xi>和序列Y=<Y1, Y2,..., Yj>中的公共子序列长度为一个状态,即为dp[i, j],每次的决策为判断

                        X[i]与Y[j]是否相等,如果相等,则引出一条到下一状态dp[i-1, j-1]的边,权重为1,否则会引出两条到下一状态的边,这两个状态分别为dp[i-1, j]与

                        dp[i, j -1],边的权重都为0;通过从目标状态开始后向求解问题,即要求出从初始状态到目标状态的最优解,则要先求出从目标状态到入射到该目标状态

                        的前一状态的最优解;

    3)问题解答:

                       由定义的状态以及状态之间的转移所做出的决策,我们可以推断出状态方程: if X[i] == Y[j], dp[i][j] = dp[i-1][j-1] + 1,

                       否则, dp[i][j] = MAX(dp[i-1][j] , dp[i][j-1]);

    代码如下: 

    #include <iostream>
    #include <string.h>
    using namespace std;
    
    const int MAX_N = 200 + 10;
    int dp[MAX_N][MAX_N];
    char X[MAX_N], Y[MAX_N];
    
    void Lcs( int XLen, int YLen )
    {
        for ( int i = 1; i <= XLen; ++i )
            for( int j = 1; j <= YLen; ++j )
            {
                if ( X[i-1] == Y[j-1] )
                    dp[i][j] = dp[i-1][j-1] + 1;
                else
                if ( dp[i-1][j] >= dp[i][j-1] )
                    dp[i][j] = dp[i-1][j];
                else
                    dp[i][j] = dp[i][j-1];
            }
    }
    
    int main()
    {
        while ( scanf( "%s %s", X, Y ) != EOF )
        {
            int XLen, YLen;
    
            memset( dp, 0, sizeof(dp) );
    
            XLen = strlen( X );
            YLen = strlen( Y );
            Lcs( XLen, YLen );
    
            printf( "%d
    ", dp[XLen][YLen] );
        }
    
        return 0;
    }
  • 相关阅读:
    优化Recorder H5录音:可边录边转码上传服务器,支持微信提供Android IOS Hybrid App源码
    设计和编写一个异步通用Picker选择器,用于时间日期、城市、商品分类的选择
    HTML5网页录音和上传到服务器,支持PC、Android,支持IOS微信
    从高德采集最新的省市区三级坐标和行政区域边界,用js在浏览器中运行
    正则表达式:后面不要包含指定的字符串内容
    基于 Angular Material 的 Data Grid 设计实现
    Ng-Matero V9 正式发布!
    Angular Schematics 三部曲之 Add
    你不需要 jQuery,但你需要一个 DOM 库
    如何编写轻量级 CSS 框架
  • 原文地址:https://www.cnblogs.com/tallisHe/p/4018083.html
Copyright © 2011-2022 走看看