Palindrome poj 1159 c++
来源:互联网 发布:英文起名软件 编辑:程序博客网 时间:2024/04/28 21:33
Palindrome
Time Limit: 3000MS Memory Limit: 65536KTotal Submissions: 52560 Accepted: 18119
Description
A 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 order to 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.
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.
Input
Your 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 letters from 'a' to 'z' and digits from '0' to '9'. Uppercase and lowercase letters are to be considered distinct.
Output
Your program is to write to standard output. The first line contains one integer, which is the desired minimal number.
Sample Input
5Ab3bd
Sample Output
2
题意:回文词是一种对称的字符串。把任意给定一个字符串用最少的步骤数,通过插入若干字符,都可以变成回文词。比如 “Ab3bd”插入2个字符后可以变成回文词“dAb3bAd”或“Adb3bdA”,但是插入少于2个的字符无法变成回文词。
;
方法一:倒序后比较,求出最长子序列,然后在用长度减去最长子序列的值即为改变的值;
代码如下:
#include<cstdio>#include<cstring>#define max(a,b) (a>b?a:b)char str[5050],str1[5050];short c[5050][5050];int main(){ int i,j,n; while(scanf("%d",&n)!=EOF) { getchar(); memset(c,0,sizeof(c)); memset(str,0,sizeof(str)); memset(str1,0,sizeof(str1)); for(i=1;i<=n;i++) scanf("%c",&str[i]); for(j=1,i=n;i>0;i--) str1[j++]=str[i]; for(i=1;i<=n;i++) for(j=1;j<=n;j++) { if(i==0||j==0) c[i][j]= 0; else if(str[i]==str1[j]) c[i][j]=c[i-1][j-1]+1; else if(str[i]!=str1[j]) c[i][j]=max(c[i][j-1],c[i-1][j]) ; } printf("%d\n",n-c[n][n]); } return 0;}
方法二:
令c(i,j)表示将子串aia(i+1)…aj变成回文词的最小添加字符数。则这此问题就是要求c(1,n)。
先来看看求c(1,10),
一。如果a1= a10则c(1,10) =c(2,9);
二。如果a1!= a10则将a1…a10变成回文词无非只有两种情况:
1.先将 a1…a9变成回文词,再在两头加上a10;
2.先将 a2…a10变成回文词,再在两头加上a1;
即c(1,10) =c(1,9)+1或c(1,10) =c(2,10)+1.
综合一和二,则变成了求三个c(1,9),c(2,10),c(2,9),如此类推:求c(1,8),c(2,9),c(2,8) ;c(2,9),c(3,10),c(3,9) ;c(2,8),c(3,9),c(3,8).。。。。。
c(i,j)满足如下递推关系:
代码如下:
#include <iostream>#include <cstdio>#include <cstring>using namespace std;short dp[5050][5050];//注意用short类型,不然会超空间;char str[5050];int main(){ int n,i,j,k; memset(dp,0,sizeof(dp)); memset(str,0,sizeof(str)); while(scanf("%d",&n)!=EOF) { scanf("%s",str+1); //getchar(); for(i=1;i<n;i++) { for(k=1;i+k<=n;k++) { j=i+k; if(str[k]==str[j]) { dp[k][j]=dp[k+1][j-1]; } else { dp[k][j]=min(dp[k][j-1]+1,dp[k+1][j]+1); } } } printf("%d\n",dp[1][n]); } return 0;}
0 0
- 【poj 1159】Palindrome 题意&题解&代码(C++)
- poj 1159 Palindrome LCS
- poj 1159 Palindrome LCS
- poj 1159 Palindrome
- poj 1159 Palindrome
- dp poj 1159 Palindrome
- poj 1159 Palindrome
- poj 1159 Palindrome
- POJ 1159 Palindrome DP
- Palindrome poj 1159
- Poj 1159 Palindrome
- poj 1159 Palindrome
- poj 1159 Palindrome 【DP】
- poj 1159Palindrome
- poj 1159 Palindrome
- POJ 1159 Palindrome
- POJ 1159 Palindrome
- Poj 1159 Palindrome
- Fragment 和 FragmentActivity
- Java实现二叉树
- 【转】POJ 1419 最大团
- 题目1182:统计单词
- 提高你的我垫的安全性
- Palindrome poj 1159 c++
- 【ZOJ】2332 Gems 最大流——判断满流
- 在Oracle的网络结构中解决连接问题
- 您如何添加一个VPN在iPad上
- 进程地址空间(三)
- 图形界面文本输入,putchar输出的一点发现--多个回车符
- 博客工具 - Live Writer
- 【iOS开发】企业版证书($299)In-House方式发布指南
- Effective C# Item32:尽可能实现小尺寸、高内聚的程序集