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 }


  • 相关阅读:
    Solaris 11 让 ls 的输出 带上颜色
    Solaris11 Vsphere client tool 的鼠标问题
    VNC Viewer连接Cent OS 时的 复制粘帖 功能
    vSphere Client的拷贝 粘帖 功能
    更改CentOS7登录画面的分辨率
    一个故意消耗内存的java程序MemoryEater
    安装CentOS7文字界面版后,无法联网,用yum安装软件提示 cannot find a valid baseurl for repo:base/7/x86_64 的解决方法
    windows 安装 Redis
    centos 安装postgresql 完整版
    centos 7 官网安装 PostgreSQL
  • 原文地址:https://www.cnblogs.com/acm-bingzi/p/3264809.html
Copyright © 2011-2022 走看看