uva 11151Longest Palindrome

来源:互联网 发布:淘宝假冒申诉 编辑:程序博客网 时间:2024/06/04 20:43

原题:
A palindrome is a string that reads the same from the left as it does from the right. For example, I, GAG and MADAM are palindromes,but ADAM is not. Here, we consider also the empty string as a palindrome.From any non-palindromic string, you can always take away some letters, and get a palindromic subsequence. For example, given the string ADAM, you remove the letter M and get
a palindrome ADA.Write a program to determine the length of the longest palindrome you can get from a string.
Input
The first line of input contains an integer T (≤ 60). Each of the next T lines is a string, whose length
is always less than 1000.
For ≥ 90% of the test cases, string length ≤ 255.
Output
For each input string, your program should print the length of the longest palindrome you can get by
removing zero or more characters from it.
Sample Input
2
ADAM
MADAM
Sample Output
3
5
大意:
给你一个字符串,你可以在这个字符串中删除0个或多个字符使得这个字符串变成回文,现在让你找最长可以变成的回文。

#include <bits/stdc++.h>using namespace std;//fstream in,out;int dp[1001][1001];char s[1001];int max3(int x,int y,int z){    return max(max(x,y),max(y,z));}int main(){//  ios::sync_with_stdio(false);    int n,ans;    scanf("%d",&n);    getchar();    while(n--)    {        gets(s);        memset(dp,0,sizeof(dp));        int len=strlen(s);        if(len==0)        {            printf("0\n");            continue;        }        for(int i=0;i<len;i++)            dp[i][i]=1;        for(int i=0;i<len-1;i++)            if(s[i]==s[i+1])                dp[i+1][i]=dp[i][i+1]=2;            else                dp[i+1][i]=dp[i][i+1]=1;        for(int l=3;l<=len;l++)        {            for(int i=0;i<=len-l+1;i++)            {                int j=l+i-1;                if(s[i]==s[j])                    dp[i][j]=max(dp[i+1][j-1]+2,dp[i][j]);                dp[i][j]=max3(dp[i+1][j],dp[i][j-1],dp[i][j]);            }        }        printf("%d\n",dp[0][len-1]);    }    return 0;}

解答:
之前做过好多有关回文串的动态规划问题了,转移方程几乎都没动笔就想出来了。利用区间动态规划的思路设置状态dp[i][j]为字母i到字母j之间字符能形成最长的回文,考虑状态转移,如果s[i]==s[j]那么dp[i][j]=dp[i+1][j-1]+2,这里初始化的时候要注意两个两个连续的相同字母要提前写出。如果s[i]!=s[j],dp[i][j]=max(dp[i+1][j],dp[i][j-1])
此题也可以用最长公共子序列做,就是让这个字符串自己和这个字符串调转求lcs问题即可。

注意,有空串!!! 同时注意回车问题

0 0
原创粉丝点击