zoukankan      html  css  js  c++  java
  • poj 1159 Palindrome (反串LCS 与 DP两种方法)

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

    LCS之前只写了一次,反串了以后都没有反应过来可以用LCS。。。

    给出反串LCS代码:

    //反串LCS 
    #include<iostream> 
    #include<cstring>
    #include<cmath>
    using namespace std;
    
    int n;
    char s[5005];
    char rs[5005];
    int dp[2][5005];///滚动数组 
    
    int lcs(char* str1,char* str2){ 
        memset(dp,0,sizeof(dp));
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
            {
                if(str1[i-1]==str2[j-1])
                    dp[i%2][j]=dp[(i-1)%2][j-1]+1;
                else
                    dp[i%2][j]=max(dp[(i-1)%2][j],dp[i%2][j-1]);
            }
        return dp[n%2][n];
    }
    int main(){
        
        while(cin>>n>>s){
        int i;
        for(i=0;i<n;i++)
            rs[i]=s[n-i-1];
        rs[i]='';
        cout<<n-lcs(s,rs)<<endl;
        }
        return 0;
    }
    View Code

    但是据说有动态规划的做法,就沿着动态规划的思路想了想,发现其实很简单

    给出基本DP做法

    /*
    动态规划思想 
    我们先从上至下的分析 
    
    以题目数据做例子
    假如字符串Ab3bd已经找到最优的最少插入方法,设为dp(Ab3bd) 
    那么,我们想得出b3bd的最优解 
    因为A与b3bd的最后一个字符d不相同,说明排除A以后,就可以省掉一个插入,则dp(b3bd)=dp(Ab3bd)-1 
    同理,dp(Ab3b)=dp(Ab3bd)-1 
    
    如果把字符串改成
    Ab3bdA
    那么dp(b3bdA)=dp(Ab3bd)=dp(Ab3bdA)+1
    
    我们就发现了关系
    if(i==j)
        dp(i....j)=dp(i+1...j)-1 //此时dp(i+1....j)==dp(i....j-1) 
    else
        dp(i....j)=min( dp(i+1....j)+1,dp(i....j-1)+1 )//此时dp(i+1...j)!=dp(i...j-1) 
    
    实现:
    设dp[i][j]为从i到j的最优解 
    可以看出,在求dp[i][j]时,dp[i+1][j]和dp[i][j-1]就已经要求出来了
    所以有i递减,j递增的顺序(显然i从n递减,j从i递增) 
    答案就是 dp[1][n] 
    
    算法时间O(n^2) 
    */ 
    #include<iostream>
    #include<cstring>
    #include<cmath>
    using namespace std;
    
    int n;
    char s[5005];
    int dp[2][5005];
    
    int main (){
        while(cin>>n>>s){
            memset(dp,0,sizeof(dp));//dp[i][i]=0
            for(int i=n-1;i>=1;i--)
                for(int j=i+1;j<=n;j++)
                {    
                    if(s[i-1]==s[j-1])
                        dp[i&1][j]=dp[(i+1)&1][j]-1;
                    else
                        dp[i&1][j]=min(dp[(i+1)&1][j],dp[i&1][j-1])+1;
                }
            cout<<dp[1][n]<<endl;
        }
        return 0;
    }

    其实后来发现s[i-1]==s[j-1]时,dp[i][j]=dp[i+1][j-1]。。。貌似好一点

  • 相关阅读:
    基于小程序开发的藏书馆
    picker(级联)组件及组件封装经验
    秒杀组件开发-可实现多种倒计时功能
    async/await 与 generator、co 的对比
    nodejs项目总结
    小程序开发小结-线下服务器域名部署等
    性能提速:debounce(防抖)、throttle(节流/限频)
    vuex数据管理-数据模块化
    vue 项目其他规范
    vue路由管理-保留滚动位置功能、按需加载模块名自定义
  • 原文地址:https://www.cnblogs.com/neverchanje/p/3568068.html
Copyright © 2011-2022 走看看