回文子序列 Palindromic Subsequence UVA 11404 动态规划 最长公共子序列

这题是最长公共子序列的变形,要注意的就是,题目要求输出最长上升子序列的字典排序最小值,最麻烦的就是这个,想了半天都没什么思路,我对最长上升子序列的理解不是很透彻。在网上看了别人的题解,都是用一个结构题来保存状态 (公共子序列的长度,公共子序列的串)我才恍然大悟,既然这样,那不是搜索一遍所有的状态的字符串就可以了吗。

#include<iostream>
#include<cstdio>
#include<string>
#include<algorithm>
#include<cstdlib>
using namespace std;
#define MAXN 1010
struct Node
{
	int l;
	string s;
}no[MAXN][MAXN];
char sm[MAXN];
int main()
{
        while(scanf("%s",sm)==1)
	{
		string s1=sm;
		int len=s1.length();
                string s2="";
		for(int i=len-1,k=0;i>=0;i--,k++)
		{
                  s2+=s1[i];
		}
	//	cout<<s2<<endl;
		s1='*'+s1;
		s2='*'+s2;
		for(int i=0;i<=len;i++)//初始化
		{
			no[0][i].l=0;no[0][i].s="";
		}
                for(int i=1;i<=len;i++)
		{
			for(int j=1;j<=len;j++)
			{
				if(s1[i]==s2[j])
				{
					no[i][j].l=no[i-1][j-1].l+1;
					no[i][j].s=no[i-1][j-1].s+s1[i];
				}
				else
				{
                                     if(no[i][j-1].l>no[i-1][j].l)
				     {
					     no[i][j].l=no[i][j-1].l;
					     no[i][j].s=no[i][j-1].s;
				     }
				     else if(no[i-1][j].l>no[i][j-1].l)
				     {
					     no[i][j].l=no[i-1][j].l;
					     no[i][j].s=no[i-1][j].s;
				     }
				     else if(no[i-1][j].l==no[i][j-1].l)
				     {
					     no[i][j].l=no[i-1][j].l;
					     if(no[i-1][j].s<no[i][j-1].s)
					     {
						     no[i][j].s=no[i-1][j].s;
					     }
					     else no[i][j].s=no[i][j-1].s;
				     }
				}
			}
		}
		int maxl=no[len][len].l;
		string str=no[len][len].s;
		string ans="";
	//	for(int i=1;i<=len;i++)
	//	{
	//		for(int j=1;j<=len;j++)
	//		{
	//			cout<<"i: "<<i<<' '<<"j: "<<j<<' '<<no[i][j].l<<' '<<no[i][j].s<<endl;
	//		}
	//	}
		if(maxl&1)
		{
                    for(int i=0;i<maxl/2;i++)
		    {
			    ans+=str[i];
		    }
		    for(int i=maxl/2;i>=0;i--)
		    {
			    ans+=str[i];
		    }
		}
		else
		{
			for(int i=0;i<maxl/2;i++)
			{
				ans+=str[i];
			}
			for(int i=maxl/2-1;i>=0;i--)
			{
				ans+=str[i];
			}
		}
		cout<<ans<<endl;
		
	}
}

你可能感兴趣的:(sequence)