• poj1159 Palindrome 动态规划


    题目:
    回文是一个对称的字符串,换句话说,这个字符串从左到右读和
    从右到左读是一样的。给出一个字符串,你要编一个程序,决定
    要插入的最少的字符个数,使得原字符串成为一个回文。
    比如,字符串”Ab3bd”中插入2个字符,使得它能变成一个
    回文("dAb3bAd" 或 "Adb3bdA")。如果插入少于2个字符,将无法产生回文。
    求最少插入几个字符,使其变成回文字符串

    分析:
    S1 = Ab3bd 的反转为
    S2 = db3ba
    要使S1变成回文字符串,可先求出S1,S2的最长公共子序列,用n-lcs(S1,S2)即可,
    本题转化为求S1,S2的最长公共子序列
    状态转移方程:
    if(s1[i]==s2[j])
    dp[i][j] = dp[i-1][j-1]+1
    else
    dp[i][j] = max{dp[i-1][j],dp[i][j-1]}
    答案为dp[n][n]

    #include <iostream>
    #include <cstring>
    using namespace std;
    #define X 5002
    short dp[X][X]; //注意到内存限制
    char s[X];
    int Max(int a,int b)
    {
    return a>b?a:b;
    }
    int main()
    {
    freopen("sum.in","r",stdin);
    freopen("sum.out","w",stdout);
    int n;
    while(cin>>n)
    {
    for(int i=1;i<=n;i++)
    cin>>s[i];
    s[n+1] = '\0';
    memset(dp,0,sizeof(dp));
    for(int i=1;i<=n;i++) //求反串与正串的LCS数
    {
    for(int j=n;j;j--) //从后面搜起,即为该反串
    {
    if(s[i]==s[j])
    dp[i][j] = dp[i-1][j+1]+1;
    else
    dp[i][j] = Max(dp[i-1][j],dp[i][j+1]);
    }
    }
    cout<<n-dp[n][1]<<endl;
    }
    return 0;
    }

  • 相关阅读:
    MySQL学习笔记(六):索引
    正则表达式基础知识,持续更新…
    js改变盒子大小(上下左右)分析
    表单自定义样式
    js拖拽分析
    javascript右键菜单分析
    简要分析javascript的选项卡和轮播图
    表单联动的总结
    浅显总结ASCII Unicode UTF-8的区别
    瀑布流知识的延伸
  • 原文地址:https://www.cnblogs.com/yejinru/p/2374719.html
Copyright © 2020-2023  润新知