1159Palindrome之求最大子序列dp
2013-10-01 21:24
323 查看
Palindrome
DescriptionA palindrome is a symmetrical string, that is, a string read identically from left to right as well as from right to left. You are to write a program which, given a string, determines the minimal number of characters to be inserted into the string in orderto obtain a palindrome.As an example, by inserting 2 characters, the string "Ab3bd" can be transformed into a palindrome ("dAb3bAd" or "Adb3bdA"). However, inserting fewer than 2 characters does not produce a palindrome.InputYour program is to read from standard input. The first line contains one integer: the length of the input string N, 3 <= N <= 5000. The second line contains one string with length N. The string is formed from uppercase letters from 'A' to 'Z', lowercase lettersfrom 'a' to 'z' and digits from '0' to '9'. Uppercase and lowercase letters are to be considered distinct.OutputYour program is to write to standard output. The first line contains one integer, which is the desired minimal number.Sample Input
Time Limit: 3000MS | Memory Limit: 65536K | |
Total Submissions: 48933 | Accepted: 16817 |
5 Ab3bdSample Output
2#include<iostream> using namespace std; #define NUMMAX 5001 short int getLCS(char s1[],char s2[],int len1,int len2); short int dp[NUMMAX][NUMMAX]; int main(){ int N; cin>>N; char s1[NUMMAX],s2[NUMMAX]; for(int i=1;i<=N;i++){ cin>>s1[i]; s2[N-i+1]=s1[i]; } cout<<N-getLCS(s1,s2,N,N); system("pause"); } short int max(int a,int b){ return a>b?a:b; } short int getLCS(char s1[],char s2[],int len1,int len2){ for(int i=0;i<=len2;i++) dp[0][i]=0; for(int i=0;i<=len1;i++) dp[i][0]=0; for(int i=1;i<=len1;i++){ for(int j=1;j<=len2;j++){ if(s1[i]==s2[j]){ dp[i][j]=max((dp[i-1][j-1]+1),dp[i][j]); }else{ dp[i][j]=max(dp[i-1][j],dp[i][j-1]); } } } return dp[len1][len2]; }解题报告copy之:
poj-1159-Palindrome-学习滚动数组
分类: POJ2013-01-26 09:14 340人阅读 评论(0) 收藏 举报题意:给你一串字符串,让你求最少加入几个字符,才能使得这个字符串是个回文串。做法:设a[i]是这个字符串,b[i]是这个字符串的逆序串。那么a[i],b[i]的最长公共子序列就是所求的字符串里拥有的最大的回文串。然后用总串长减去最大的回文串长度即为所求。求最长公共子序列的公式为:dp[i][j]=max(dp[i-1] [j],dp[i][j-1])if(a[i]==b[i])dp[i][j]=max(dp[i][j],dp[i-1][j-1]+1);如果直接求的话,势必要开一个5001*5001的数组,铁定MLE。有一下两种解决方法:1,开short int型数组这是poj返回的结果:2,运用动态数组。根据dp滚动的过程我们可以知道,dp【i】【j】的值不会与dp[i-2][0.....n]的值有关系。那么可以把dp[i][j]的值覆盖到dp[i-2][j]上。即dp[i][j]为dp[i%2][j];poj返回的结果:对比以上两种方法,显而易见的可以得出2的方法很节约空间,就是耗时略长。1,short int数组[html] view plaincopy#include<iostream>#include<stdio.h>#include<string.h>#define max(a,b) (a>b?a:b)using namespace std;short int dp[5001][5001];int main(){int a[5001];int b[5001];int i,j;int n;char str;cin>>n;getchar();for(i=1;i<=n;i++){scanf("%c",&str);a[i]=str;b[n-i+1]=str;}for(i=0;i<=n;i++){dp[i][0]=0;dp[0][i]=0;}for(i=1;i<=n;i++){for(j=1;j<=n;j++){dp[i][j]=max(dp[i][j-1],dp[i-1][j]);if(a[i]==b[j]){dp[i][j]=max(dp[i][j],dp[i-1][j-1]+1);}}}int len;len=dp;printf("%d\n",n-len);return 0;}2,滚动数组[html] view plaincopy#include<iostream>#include<stdio.h>#include<string.h>using namespace std;int main(){int a[5001];int b[5001];int dp[10][5001];int i,j;int n;char str;cin>>n;getchar();for(i=1;i<=n;i++){scanf("%c",&str);a[i]=str;b[n-i+1]=str;}dp[1][0]=dp[0][0]=0;for(i=0;i<=n;i++){dp[0][i]=0;}for(i=1;i<=n;i++){for(j=1;j<=n;j++){dp[i%2][j]=max(dp[i%2][j-1],dp[(i-1)%2][j]);if(a[i]==b[j]){dp[i%2][j]=max(dp[i%2][j],dp[(i-1)%2][j-1]+1);}}}int len;len=dp[n%2];printf("%d\n",n-len);return 0;}
相关文章推荐
- ACM-DP之最大连续子序列——hdu1231
- hdu 1003 最大最长子序列 dp
- 【HDU 1231】最大连续子序列(DP)
- HDU 1231 最大连续子序列 (DP)
- 九度OJ 1077:最大序列和 (DP)
- 最大连续子序列(HDU 1231 DP)
- HDU 1231 最大连续子序列 (线性dp)
- dp求最大和序列
- DP_最大子序列和(HDU_1003)
- HDU-1231-最大连续子序列(DP)
- HDU1003(最大连续子序列和DP)
- hdu杭电1003 dp 连续子序列最大值
- 最大连续子序列 (dp)HDU 1231
- CF260--C--dp<最大不连续子序列和>
- hdu 1231 最大连续子序列(DP)
- 【HDU 1231】最大连续子序列(DP)
- Hdu 1231 最大连续子序列(DP)
- dp 最大递增子序列
- POJ 2479 + POJ 2593(DP 最大双子序列 ^_^)
- HDU 1231:最大连续子序列(DP)