UVa11404 - Palindromic Subsequence(区间DP+打印路径)
题目大意
给定一个字符串,要求你删除尽量少的字符,使得原字符串变为最长回文串,并把回文串输出,如果答案有多种,则输出字典序最小的
题解
有两种解法,第一种是把字符串逆序,然后求两个字符串的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+打印路径)的更多相关文章
- POJ 1141 Brackets Sequence(区间DP, DP打印路径)
Description We give the following inductive definition of a “regular brackets” sequence: the empty s ...
- HDU4632:Palindrome subsequence(区间DP)
Problem Description In mathematics, a subsequence is a sequence that can be derived from another seq ...
- 【noi 2.6_2000】&【poj 2127】 最长公共子上升序列 (DP+打印路径)
由于noi OJ上没有Special Judge,所以我是没有在这上面AC的.但是在POJ上A了. 题意如标题. 解法:f[i][j]表示a串前i个和b串前j个且包含b[j]的最长公共上升子序列长度 ...
- HDU 4632 Palindrome subsequence(区间dp,回文串,字符处理)
题目 参考自博客:http://blog.csdn.net/u011498819/article/details/38356675 题意:查找这样的子回文字符串(未必连续,但是有从左向右的顺序)个数. ...
- HDU 4632 Palindrome subsequence (区间DP)
题意 给定一个字符串,问有多少个回文子串(两个子串可以一样). 思路 注意到任意一个回文子序列收尾两个字符一定是相同的,于是可以区间dp,用dp[i][j]表示原字符串中[i,j]位置中出现的回文子序 ...
- [HDU4362] Palindrome subsequence (区间DP)
题目链接 题目大意 给你几个字符串 (1<len(s)<1000) ,要你求每个字符串的回文序列个数.对于10008取模. Solution 区间DP. 比较典型的例题. 状态定义: 令 ...
- hdu4632 Palindrome subsequence (区间dp)
题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=4632 题意:求回文串子串的的个数. 思路:看转移方程就能理解了. dp[i][j] 表示区 ...
- POJ 题目1141 Brackets Sequence(区间DP记录路径)
Brackets Sequence Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 27793 Accepted: 788 ...
- poj 1458 Common Subsequence(区间dp)
题目链接:http://poj.org/problem?id=1458 思路分析:经典的最长公共子序列问题(longest-common-subsequence proble),使用动态规划解题. 1 ...
随机推荐
- ASP.NET MVC 3 Razor Views in SharePoint
http://tqcblog.com/2011/01/22/asp-net-mvc-3-razor-views-in-sharepoint/ ASP.NET MVC 3 has just been r ...
- Windows store app Settings 的 应用 ( viewmodel + windows.storage)
1.在首页 加入 一个元素(加下滑线的).此元素绑定了两个属性 <!DOCTYPE html> <html> <head> <meta charset=&qu ...
- HTML5-canvas实例:刮刮乐游戏
实现方法: (1)利用canvas画布,fillRect()描绘出一个矩形(不是透明),定位盖在某个标签如div上面(这个标签写着中奖的信息) (2)globalCompositeOperation ...
- Ubuntu添加PPA源
转自Ubuntu添加PPA源 什么是PPA PPA,表示Personal Package Archives,也就是个人软件包集 很多软件包由于各种原因吧,不能进入官方的Ubuntu软件仓库.为了方便U ...
- Unity3D研究院之在MAC上脚本XlsxWriter写入Excel .xlsx格式
原地址:http://www.xuanyusong.com/archives/3011 以前找了很久可以跨平台支持读写Excel的工具,我也试了很多种DLL.可在Windows上各个完美支持,可是在M ...
- linux awk命令详解(转)
http://www.cnblogs.com/ggjucheng/archive/2013/01/13/2858470.html 简介 awk是一个强大的文本分析工具,相对于grep的查找,sed的编 ...
- 练习--LINUX进程间通信之有名管理FIFO
从FIFO中读取数据: 约定:如果一个进程为了从FIFO中读取数据而阻塞打开FIFO,那么称该进程内的读操作为设置了阻塞标志的读操作. 如果有进程写打开FIFO,且当前FIFO内没有数据,则对于设置了 ...
- [线段树]HDOJ5091 Beam Cannon
题意:给n, w, h (1 <= N <= 10000,1 <= W <= 40000,1 <= H <= 40000) $w\times h$是可以射到的范围 ...
- ANDROID_MARS学习笔记_S01原始版_003_对话框
1.AndroidManifest.xml <?xml version="1.0" encoding="utf-8"?> <manifest ...
- 《深入理解linux内核》第三章 进程
进程的七种状态 在内核源码的 include/linux/sched.h文件中: task_struct的status可表示 #define TASK_RUNNING 0 #define TASK_I ...