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 ...
随机推荐
- hive 中的Sort By、 Order By、Cluster By、Distribute By 区别
Order by: order by 会对输入做全局排序,因此只有一个reducer(多个reducer无法保证全局有序)只有一个reducer,会导致当输入规模较大时,需要较长的计算时间.在hive ...
- mvvm windows app DataBinding
前台html 绑定(view):<div id="aa" data-win-bind="innerText:UserData.word" style=&q ...
- objective-c常用数学方法
1. 三角函数 double sin (double);正弦 double cos (double);余弦 double tan (double);正切 2 .反三角函数 double as ...
- 转 JavaScript 操作select控件大全(新增、修改、删除、选中、清空、判断存在等)
收藏一下 1.判断select选项中 是否存在Value=”paraValue”的Item2.向select选项中 加入一个Item3.从select选项中 删除一个Item4.删除select中选中 ...
- csuoj 1355: 地雷清除计划
这是一个非常神奇的题: 感觉像一个模拟搜索: 但是竟然可以用网络流来解决: 直接粘题解把: 如果不能走通的话,必然说明能够从右上角(图外面)沿雷“跳” ,一直可以“跳”左下角(图外面) ,因此建好图之 ...
- 练习--LINUX进程间通信之信号SIGNAL
同样的,信号也不要太迷信可靠信号及不及靠信号,实时或非实时信号. 但必须要了解这些信号之间的差异,函数升级及参数,才能熟练运用. ~~~~~~~~~~~~~~~~ 信号本质 信号是在软件层次上对中断机 ...
- activity的测试工程activiti-explorer使用
1. activiti-explorer默认使用h2数据库,第一步要修改db.properties的配置,如果使用其他数据库的话,务必放入驱动包,oracle的ojdbc4不能用,会报错,要使用版本高 ...
- 利用动软代码生成器 自动生成LINQ需要用的数据实体类 (转)
首先先建立一个模板 名称随意 我起的“生成数据实体.cmt” 代码如下: <#@ template language="c#" HostSpecific="True ...
- SQLite入门与分析(八)---存储模型(2)
3.页面结构(page structure) 数据库文件分成固定大小的页面.SQLite通过B+tree模型来管理所有的页面.页面(page)分三种类型:要么是tree page,或者是overflo ...
- 分析Java的类加载器与ClassLoader(二):classpath与查找类字节码的顺序,分析ExtClassLoader与AppClassLoader的源码
先回顾一下classpath classpath的作用: classpath的作用是指定查找类的路径:当使用java命令执行一个类(类中的main方法)时,会从classpath中进行查找这个类. 指 ...