题目大意

给定一个字符串,要求你删除尽量少的字符,使得原字符串变为最长回文串,并把回文串输出,如果答案有多种,则输出字典序最小的

题解

有两种解法,第一种是把字符串逆序,然后求两个字符串的LCS,并记录LCS,长度就等于最长回文串的长度,不过求出来的LCS不一定是回文串,例如下面这个例子

        s  = 1 5 2 4 3 3 2 4 5 1
reverse(s) = 1 5 4 2 3 3 4 2 5 1
LCS = 1 5 2 3 3 4 5 1
所以我们只需要LCS的前半段即可

代码:

#include <cstdio>
#include <algorithm>
#include <string>
#include <iostream>
#include <utility>
using namespace std;
#define MAXN 1005
string a,b;
pair<int,string>dp[MAXN][MAXN];
int main()
{
while(cin>>a)
{
int len=a.length();
b=a;
reverse(b.begin(),b.end());
for(int i=0;i<len;i++)
{
dp[0][i].first=0,dp[0][i].second="";
dp[i][0].first=0,dp[i][0].second="";
}
for(int i=0;i<len;i++)
for (int j=0;j<len;j++)
if(a[i]==b[j])
{
dp[i+1][j+1].first=dp[i][j].first+1;
dp[i+1][j+1].second=dp[i][j].second+a[i];
}
else
{
if(dp[i+1][j].first>dp[i][j+1].first)
{
dp[i+1][j+1].first=dp[i+1][j].first;
dp[i+1][j+1].second=dp[i+1][j].second;
}
else
if(dp[i+1][j].first==dp[i][j+1].first)
{
dp[i+1][j+1].first=dp[i][j+1].first;
dp[i+1][j+1].second=min(dp[i][j+1].second,dp[i+1][j].second);
}
else
{
dp[i+1][j+1].first=dp[i][j+1].first;
dp[i+1][j+1].second=dp[i][j+1].second;
}
}
int lens=dp[len][len].first;
string s=dp[len][len].second;
if(lens&1)
{
int t=lens/2;
for(int i=0;i<=t;i++)
cout<<s[i];
for(int i=t-1;i>=0;i--)
cout<<s[i];
cout<<endl;
}
else
{
int t=lens/2;
for(int i=0;i<t;i++)
cout<<s[i];
for(int i=t-1;i>=0;i--)
cout<<s[i];
cout<<endl;
}
}
return 0;
}

第二种方法和POJ1159一样,不过是多了个路径而已

代码:

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <iostream>
#include <string>
using namespace std;
#define MAXN 1005
string s;
int dp[MAXN][MAXN];
string path[MAXN][MAXN];
int main()
{
int n;
while(cin>>s)
{
memset(dp,0,sizeof(dp));
int n=s.length();
for(int i=n-1; i>=0; i--)
for(int j=i; j<n; j++)
if(s[i]==s[j])
{
dp[i][j]=dp[i+1][j-1];
if(i!=j)path[i][j]=s[i]+path[i+1][j-1]+s[j];
else
path[i][j]=s[i];
}
else
{
if(dp[i+1][j]<dp[i][j-1])
{
dp[i][j]=dp[i+1][j]+1;
path[i][j]=path[i+1][j];
}
else
if(dp[i+1][j]==dp[i][j-1])
{
dp[i][j]=dp[i+1][j]+1;
path[i][j]=min(path[i+1][j],path[i][j-1]);
}
else
{
dp[i][j]=dp[i][j-1]+1;
path[i][j]=path[i][j-1];
}
}
cout<<path[0][n-1]<<endl;
}
return 0;
}

UVa11404 - Palindromic Subsequence(区间DP+打印路径)的更多相关文章

  1. POJ 1141 Brackets Sequence(区间DP, DP打印路径)

    Description We give the following inductive definition of a “regular brackets” sequence: the empty s ...

  2. HDU4632:Palindrome subsequence(区间DP)

    Problem Description In mathematics, a subsequence is a sequence that can be derived from another seq ...

  3. 【noi 2.6_2000】&【poj 2127】 最长公共子上升序列 (DP+打印路径)

    由于noi OJ上没有Special Judge,所以我是没有在这上面AC的.但是在POJ上A了. 题意如标题. 解法:f[i][j]表示a串前i个和b串前j个且包含b[j]的最长公共上升子序列长度 ...

  4. HDU 4632 Palindrome subsequence(区间dp,回文串,字符处理)

    题目 参考自博客:http://blog.csdn.net/u011498819/article/details/38356675 题意:查找这样的子回文字符串(未必连续,但是有从左向右的顺序)个数. ...

  5. HDU 4632 Palindrome subsequence (区间DP)

    题意 给定一个字符串,问有多少个回文子串(两个子串可以一样). 思路 注意到任意一个回文子序列收尾两个字符一定是相同的,于是可以区间dp,用dp[i][j]表示原字符串中[i,j]位置中出现的回文子序 ...

  6. [HDU4362] Palindrome subsequence (区间DP)

    题目链接 题目大意 给你几个字符串 (1<len(s)<1000) ,要你求每个字符串的回文序列个数.对于10008取模. Solution 区间DP. 比较典型的例题. 状态定义: 令 ...

  7. hdu4632 Palindrome subsequence (区间dp)

    题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=4632 题意:求回文串子串的的个数. 思路:看转移方程就能理解了. dp[i][j] 表示区 ...

  8. POJ 题目1141 Brackets Sequence(区间DP记录路径)

    Brackets Sequence Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 27793   Accepted: 788 ...

  9. poj 1458 Common Subsequence(区间dp)

    题目链接:http://poj.org/problem?id=1458 思路分析:经典的最长公共子序列问题(longest-common-subsequence proble),使用动态规划解题. 1 ...

随机推荐

  1. OFBiz进阶之HelloWorld(一)创建热部署模块

    创建热部署模块 参考文档 https://cwiki.apache.org/confluence/display/OFBIZ/OFBiz+Tutorial+-+A+Beginners+Developm ...

  2. Oracle目录结构及创建新数据库

    oracle目录结构 当需要创建新的数据仓库时我可以用 Database Configuration Assistant(数据库配置助手) admin 存放创建的不同数据库 cfgtoollogs c ...

  3. c++ 重定位输出到DOS

    #define USE_WIN32_CONSOLE int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTST ...

  4. SWFUpload 按钮显示问题

    问题: 今天遇到一个这样的问题,我用Vs2010打开用SWFUpload上传文件的网页时,按钮显示不出来,试了好多方法,终于被我找到了! 解决方法: 原来是vs2010自带的Asp.net Devel ...

  5. c++中的static关键字

    1.在函数体中,一个被声明为静态的变量在这一函数被调用的过程中维持其值不变. 2.在模块内(但在函数外),比如在某一个C源文件内,一个被声明为静态的变量可以被该模块内的所有函数调用,但不能被模块外的函 ...

  6. 在C#中关于excel的导入和导出操作

    一.先来看看最常见的导入操作吧! private void Import() { //打开excel选择框 OpenFileDialog frm = new OpenFileDialog(); frm ...

  7. listview加载性能优化

    在android开发中Listview是一个很重要的组件,它以列表的形式根据数据的长自适应展示具体内容,用户可以自由的定义listview每一列的布局,但当listview有大量的数据需要加载的时候, ...

  8. [杂题]CSUOJ1276 Counting Route Sequence

    题目链接 题意:从1号点走到n号点(每条边只能走一次, 两结点间的边数必定为奇数) 问 经过结点不同顺序的方式有多少种(如1->2->3->4和1->3->2->4 ...

  9. ANDROID_MARS学习笔记_S01原始版_017_绑定SERVICE

    一.流程 1.编写service,重写onBind(Intent intent),返回自定义的Binder 2.自写义Binder,提供一个可访问的方法,以传递数据 3.点击界面按钮会开启servic ...

  10. money 和 smallmoney

    代表货币或货币值的数据类型. 数据类型 范围 存储 money -922,337,203,685,477.5808 到 922,337,203,685,477.5807 8 字节 smallmoney ...