hdu-1513-Palindrome

Palindrome

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 4052    Accepted Submission(s): 1377


Problem 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.
 

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
  
  
5 Ab3bd
 

Sample Output
  
  
2
 

Source



题目分析:

意思就是让你在一个字符串中添几个字符让这个字符串成为回文串        这你要理解  lcs    如果明白了lcs是怎么查最长子序列的话就很好办了

比如说   123     321    用lcs 查一遍等于len=1              123321       这个串就是回文  但是我刚开始的思路就是把  123321  分成   123     321    两个串查他们的公共子串 然后总长度 6-2*len=4   但是这个串应该是0 的。然后我又看了看lcs     发现   abcsff      cbaiik    这个查出来是1     abcsff     iiabck   这个查出来就是  3    该是对lcs的理解就是错的我理解成有多少个相同字符就是多少呢!

那么知道了lcs 是怎么查的这个就好办了,只需把原串倒序一下  对这两个进行查找就行了,如果是回文串结果肯定是总长度了 如果不是回文那么查出的就是公共子串的长度那么    总长度减去公共长度及时需要添的了                                       比如 abcf  g cbah    倒置之后是    habc g  fcba    红色部分和绿色部分只能查出有个长度为1的子串(上边已经说过lcs是怎么查的了)那么倒置后就相当于红色部分对红色部分查那么在纸上掩饰一边查找的结果应该是 5    abcg 一个长4 还有 cbah   对cbah  查出一个共5个  9-5=4   那么这个在添  4个就是回文了看看是不是



另外这个数据有点大需要用滚动数组   下边是看别人的滚动数组解析



相信很多同学都学过时间复杂度,在以前的很多程序编译里面我们也都看到过时间复杂度的优化,因为这个是一个很重要的因素,而且一般的ACM题目都是卡的时间,卡空间复杂度的不是很多,但是这里就卡了空间复杂度,这里我们介绍一种优化空间复杂度的方法——滚动数组。

下面首先介绍一下这个思想:滚动数组很适合用在二维DP而且是数组在很大时,可以节省内存,消除超内存的隐患!具体思想还是看了网上的资料,转载一个,共同享用吧!

滚动数组 举个简单的例子:
int i,d[100];
d[0]=1;d[1]=1;
for(i=2;i<100;i++)
d[i]=d[i-1]+d[i-2];
printf("%d",d[99]);
上面这个循环d[i]只需要解集中的前2个解d[i-1]和d[i-2];
为了节约空间用滚动数组的方法

int d[3];
d[0]=1;d[1]=1;
for(i=2;i<100;i++)
d[i%3]=d[(i-1)%3]+d[(i-2)%3];
printf("%d",d[99%3]);

注意上面的运算,我们只留了最近的3个解,数组好象在“滚动”一样,所以叫滚动数组

对于二维数组也可以用这种方法 例如:
int i,j,d[100][100];
for(i=1;i<100;i++)
    for(j=0;j<100;j++)
        d[i][j]=d[i-1][j]+d[i][j-1];

上?的d[i][j]忪便赖于d[i-1][j],d[i][j-1];
迿用滚动数组
int i,,j,d[2][100];
for(i=1;i<100;i++)
    for(j=0;j<100;j++)
        d[i%2][j]=d[(i-1)%2][j]+d[i%2][j-1];


#include<cstdio>
#include<cstring>
#define max(a,b)  (a>b?a:b)
int main()
{
	int n;
	while(~scanf("%d",&n))
	{
		int dp[2][5010];
		char str1[5010],str2[5010];
		scanf("%s",str1);
	    strcpy(str2,str1);  
        strrev(str2);  //  strrev( ) c里面的倒置函数 
        memset(dp,0,sizeof(dp));
		for(int i=1;i<=n;i++)
		   for(int j=1;j<=n;j++)
		   {
		   	   if(str1[i-1]==str2[j-1])
		   	      dp[i%2][j]=dp[(i-1)%2][j-1]+1;
		   	    else  dp[i%2][j]=max(dp[(i-1)%2][j],dp[i%2][j-1]);
		   }
		   printf("%d\n",n-dp[n%2][n]);
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

stormsha

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值