poj 1159 palindrome-----动态规划

9 篇文章 0 订阅

题目大意 给出一个字符串,求至少需要插入多少个字符使原字符串变为回文串(如abcde不是回文串,而abcba是回文串);

算法 结合最长公共子序列问题,把原串(长度为n)逆序存储一下,求其与原串的最长公共字串长度k,则n-k即为所求。

注意 5000*5000的二维数组不会爆空间,但实际上完全可以滚动第一维,用滚动数组存储显然节省了相当的空间。

代码实现-非滚动版 

<span style="font-size:14px;">#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
using namespace std;
short f[5001][5001];

int main()
{
	int n;
	cin>>n;
	scanf("\n");
	char s1[n+1],s2[n+1];
	for (int i=1;i<=n;i++)
	scanf("%c",&s1[i]);
	for (int i=1;i<=n;i++)
	s2[n-i+1]=s1[i];
	int ans=0;
	for (int i=1;i<=n;i++) //求最长公共字串长;
	for (int j=1;j<=n;j++)
	{
		if (s1[i]==s2[j])
		f[i][j]=f[i-1][j-1]+1;  
		else 
		f[i][j]=max(f[i][j-1],f[i-1][j]);  //可以看出,f[i][j]状态至于f[i-1][..]和f[i][..]有关,因此完全可以滚动第一维;
	}
	cout<<n-f[n][n];
	return 0;
}
</span>

滚动版

<span style="font-size:14px;">#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<cstdio>
using namespace std;
short f[2][5001];

int main()
{
	int n;
	cin>>n;
	scanf("\n");
	char s1[n+1],s2[n+1];
	for (int i=1;i<=n;i++)
	scanf("%c",&s1[i]);
	for (int i=1;i<=n;i++)
	s2[n-i+1]=s1[i];
	int ans=0;
	int pre=0,now=1; 
	for (int i=1;i<=n;i++)
	{
		for (int j=1;j<=n;j++)
	        {
	        	if (s1[i]==s2[j])
	        	f[now][j]=f[pre][j-1]+1;
	        	else 
	        	f[now][j]=max(f[now][j-1],f[pre][j]);	
    	        }
		swap(pre,now); //枚举完j后pre与now交换,是滚动数组实现的关键;
	}
	
	cout<<n-f[pre][n];
	return 0;
}
</span>



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值