zoukankan      html  css  js  c++  java
  • POJ 1159 Palindrome(LCS)

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

    题目大意:给定一串字符,添加最少的字符,使之成为回文串。

    Sample Input

    5
    Ab3bd

    Sample Output

    2

    分析:这道题目之前有做过,就是将原字符串逆序得到另一个字符串,求它们的最长公共子序列,这样就能求得它的可以构成回文的最长字符数,用n减去即为添加最少可使之成为回文的数目。

    可恨的是之前一直超内存,看了别人的解题报告,原来定义dp[MAX][MAX]时,不用int型,而是short型,内存只占int的一半(见上一篇日志)


    另外逆序字符串可以不用新开一个数组,也可以直接在原数组上从后往前循环。

    代码如下:
     1 # include<stdio.h>
     2 # include<string.h>
     3 
     4 #define MAX 5005
     5 
     6 int max(int a,int b,int c){
     7     int temp;
     8     temp = a>b ? a :b;
     9     return temp>c ?temp :c ;
    10 }
    11 char s[MAX],t[MAX];
    12 short dp[MAX][MAX];    //定义的类型为short
    13 
    14 int main(){
    15     int i,j,n;
    16     while(scanf("%d",&n)!=EOF){
    17         scanf("%s",s);
    18         for(i=0;i<n;i++)
    19             t[i] = s[n-i-1];
    20         t[n] = 0;
    21         memset(dp,0,sizeof(dp));
    22         for(i=1;i<=n;i++){
    23             for(j=1;j<=n;j++){
    24                 if(s[i-1] == t[j-1])
    25                     dp[i][j] = dp[i-1][j-1] + 1;
    26                 dp[i][j] = max(dp[i][j],dp[i-1][j],dp[i][j-1]);
    27             }    
    28         }
    29         printf("%d
    ",n-dp[n][n]);
    30     }
    31     return 0;
    32 }
    另一种方法:dp[i][j]表示从第i个字符到第j个字符能构成的回文添加的最少字符。
     1 #include <stdio.h>
     2 #define Min(a,b) (a<b?a:b)
     3 const int MAX = 5001;
     4 char ch[MAX];
     5 short dp[MAX][MAX]={0};
     6 int main()
     7 {
     8     int lenth, i, j;
     9     while(scanf("%d%s",&lenth, ch+1)!=EOF)
    10     {
    11         for(i=lenth;i>0;i--)    //自底向上
    12         {    
    13             for(j=i+1;j<=lenth;j++)
    14             {
    15                 if(ch[i]==ch[j]){
    16                     dp[i][j] = dp[i+1][j-1];
    17                 }
    18                 else{
    19                     dp[i][j] = Min(dp[i+1][j],dp[i][j-1])+1;
    20                 }
    21             }
    22         }
    23         printf("%d
    ",dp[1][lenth]);
    24     }
    25     return 0;
    26 }
    
    

     可是在某些变态的OJ里,上面的方法仍然不能AC,这是需要引入滚动数组优化空间,比如在第一种方法之上

    代码如下:

     1 # include<stdio.h>
     2 # include<string.h>
     3 
     4 #define MAX 5005
     5 
     6 int max(int a,int b,int c){
     7     int temp;
     8     temp = a>b ? a :b;
     9     return temp>c ?temp :c ;
    10 }
    11 char s[MAX],t[MAX];
    12 short dp[2][MAX];
    13 
    14 int main(){
    15     int i,j,n;
    16     while(scanf("%d",&n)!=EOF){
    17         scanf("%s",s);
    18         for(i=0;i<n;i++)
    19             t[i] = s[n-i-1];
    20         t[n] = 0;
    21         memset(dp,0,sizeof(dp));
    22         for(i=1;i<=n;i++){
    23             for(j=1;j<=n;j++){
    24                 if(s[i-1] == t[j-1])
    25                     dp[i%2][j] = dp[(i-1)%2][j-1] + 1;
    26                 dp[i%2][j] = max(dp[i%2][j],dp[(i-1)%2][j],dp[i%2][j-1]);
    27             }    
    28         }
    29         printf("%d
    ",n-dp[n%2][n]);
    30     }
    31     return 0;
    32 }


  • 相关阅读:
    P1371 NOI元丹
    最小费用最大流
    City Game UVALive
    P2389 电脑班的裁员
    P1959 遗址_NOI导刊2009普及(6)
    P2700 逐个击破
    P1630 求和
    P4310 绝世好题
    java常用类:1。包装类(以Integer类为例)2.String类 3.StringBuffer
    java异常,异常处理,异常类 关键字:throws 和 throw 自定义的异常类
  • 原文地址:https://www.cnblogs.com/acm-bingzi/p/3264809.html
Copyright © 2011-2022 走看看