zoukankan      html  css  js  c++  java
  • nyist oj 37 回文字符串 (动态规划经典)

    回文字符串

    时间限制:3000 ms  |  内存限制:65535 KB
    难度:4
    描写叙述
    所谓回文字符串,就是一个字符串。从左到右读和从右到左读是全然一样的。比方"aba"。当然,我们给你的问题不会再简单到推断一个字符串是不是回文字符串。如今要求你,给你一个字符串,可在任何位置加入字符。最少再加入几个字符,能够使这个字符串成为回文字符串。
    输入
    第一行给出整数N(0<N<100)
    接下来的N行。每行一个字符串,每一个字符串长度不超过1000.
    输出
    每行输出所需加入的最少字符数
    例子输入
    1
    Ab3bd
    例子输出
    2
    来源

    IOI 2000

    開始看到这道题的时候,一时想不出用什么非常好的方法来做。看到分类是在动态规划,也大致往这方面想。看了别人的思路。顿时茅塞顿开啊,直接把给定的字符串倒转,然后再和原字符串一起,求他们的最长公共序列,然后再拿字符串的长度减去他们的最长公共序列的长度,得到的就是要加入的最小的字符数。想到了这个地方,这个题目就非常好解啦;直接用LIC水过,状态方程式也和前面做过的题一样;

    #include <cstdio>
    #include <cstring>
    #define max(a,b) a>b?a:b
    const int maxn=1001;
    char a[maxn],b[maxn];
    int dp[maxn][maxn];//昨天晚上把DP的类型设置成了char型,然后提交一直wa,刷屏了。。

    。不应该啊!。 int main() { int n,i,j,len; scanf("%d",&n); while(n--) { memset(a,0,sizeof(a)); memset(dp,0,sizeof(dp)); scanf("%s",a); len=strlen(a); for(i=len-1,j=0;i>=0;i--) b[j++]=a[i]; for(i=1;i<=len;i++) { for(j=1;j<=len;j++) { if(a[i-1]==b[j-1]) dp[i][j]=dp[i-1][j-1]+1;//递推关系 else dp[i][j]=max(dp[i-1][j],dp[i][j-1]); } } printf("%d ",len-dp[len][len]); } }

    看到别人的写的,用了还有一种思路,也是动态规划。可是递推关系有一点不同;有点没看懂;

    省去了倒转的环节

     
    #include<stdio.h>  
    #include<string.h>  
      
    int f[1005][1005];  
      
    int main()  
    {  
        int n;  
        scanf("%d",&n);  
        while (n--)  
        {  
            char s[1005];  
            scanf("%s",s);  
            int k,i,j,l=strlen(s);  
      
            for (i=0;i<l;++i) f[i][i]=0;  
      
            for (k=2;k<=l;++k)  
                {  
                    for (i=0;i<=l-k;++i)  
                        {  
                        int p=i+k-1;  
                        if (s[i]==s[p])  
                            {  
                                f[i][p]=f[i+1][p-1];  
                            }  
                        else   
                            {  
                                f[i][p]=1+(f[i][p-1]<f[i+1][p]?

    f[i][p-1]:f[i+1][p]); } } } printf("%d ",f[0][l-1]); memset(f,0,sizeof(f)); } return 0; }


    看到别人的最优代码,内存占用的非常小。值得学习,另一种滚动数组。好像能够节约内存。还没有接触过;

     
     
    #include<stdio.h>
    #include<string.h>
    using namespace std;
    int m[1000],i,j,t1,t2,len;
    char s[1001];
    int main() {
      int N;
      scanf("%d",&N);
      while(N--){
        scanf("%s",s);
        len=strlen(s);
        for(i=len-1;i>=0;i--){
          m[i]=0;
          t1=m[i];
          for(j=i+1;j<len;j++){
            t2=m[j];
            if(s[i]==s[j])
              m[j]=t1;
            else
              m[j]=m[j-1]<m[j]?m[j-1]+1:m[j]+1;
            t1=t2;
          }
        }
        printf("%d
    ",m[len-1]);
      }
    }                
    



  • 相关阅读:
    ptyhon异步开发aiohttp
    python异步编程asyncio
    python ThreadPoolExecutor线程池和ProcessPoolExecutor进程池
    liunx 使用flask + nginx + gunicorn 部署项目
    liunx安装python3.6.8
    Grafana设置mysql为数据源
    使用pyhdfs连接HDFS进行操作
    七、Hadoop搭建Hbase
    六、Zookeeper运行环境
    五、Hadoop搭建Hive
  • 原文地址:https://www.cnblogs.com/wzjhoutai/p/7222299.html
Copyright © 2011-2022 走看看