zoukankan      html  css  js  c++  java
  • NYOJ-37 回文字符串 —— LCS变形

    题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=37


    题解:

    一开始想从两边向中间添加字符,发现这样不是最优的。因为加入字符之后,这些原本存在的字符是离散的,所以就不能用顺序的方法去添加。

    正确做法是将字符串逆过来,与原字符串求最大公共子序列。最大公共子序列即是不需要添加的字符序列,那么剩下的len-dp[len][len]就是需要添加进去的最少字符个数,使得原来的字符串刚好构成回文串。


    代码如下:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cstdlib>
     5 #include <string>
     6 #include <vector>
     7 #include <map>
     8 #include <set>
     9 #include <queue>
    10 #include <sstream>
    11 #include <algorithm>
    12 using namespace std;
    13 #define pb push_back
    14 #define mp make_pair
    15 #define ms(a, b)  memset((a), (b), sizeof(a))
    16 #define eps 0.0000001
    17 typedef long long LL;
    18 const int INF = 2e9;
    19 const LL LNF = 9e18;
    20 const int mod = 1e9+7;
    21 const int maxn = 1000+10;
    22 
    23 char s[maxn];
    24 int dp[maxn][maxn];
    25 
    26 void solve()
    27 {
    28     scanf("%s",s);
    29     int len = strlen(s);
    30     for(int i = 0; i<len; i++)
    31     {
    32         for(int j = 0; j<len; j++)
    33         {
    34             if(s[i]==s[len-1-j])
    35                 dp[i+1][j+1] = dp[i][j] + 1;
    36             else
    37                 dp[i+1][j+1] = max(dp[i][j+1],dp[i+1][j]);
    38         }
    39     }
    40     printf("%d
    ", len-dp[len][len]);
    41 }
    42 
    43 int main()
    44 {
    45     int T;
    46     scanf("%d",&T);
    47     while(T--){
    48         ms(dp,0);
    49         solve();
    50     }
    51 }
    View Code


  • 相关阅读:
    Android编译环境配置(Ubuntu 14.04)
    Android中的接口回调技术
    我为什么要拒绝Ctrl+C和Ctrl+V?
    软件设计网站大全
    国内及Github优秀开发人员列表
    Linux常用指令
    Linux系统目录结构
    UML图
    Android软件设计---Dumpsys工具使用
    Android应用程序Monkey测试
  • 原文地址:https://www.cnblogs.com/DOLFAMINGO/p/7538711.html
Copyright © 2011-2022 走看看