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 ...
随机推荐
- OFBiz进阶之HelloWorld(一)创建热部署模块
创建热部署模块 参考文档 https://cwiki.apache.org/confluence/display/OFBIZ/OFBiz+Tutorial+-+A+Beginners+Developm ...
- Oracle目录结构及创建新数据库
oracle目录结构 当需要创建新的数据仓库时我可以用 Database Configuration Assistant(数据库配置助手) admin 存放创建的不同数据库 cfgtoollogs c ...
- c++ 重定位输出到DOS
#define USE_WIN32_CONSOLE int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTST ...
- SWFUpload 按钮显示问题
问题: 今天遇到一个这样的问题,我用Vs2010打开用SWFUpload上传文件的网页时,按钮显示不出来,试了好多方法,终于被我找到了! 解决方法: 原来是vs2010自带的Asp.net Devel ...
- c++中的static关键字
1.在函数体中,一个被声明为静态的变量在这一函数被调用的过程中维持其值不变. 2.在模块内(但在函数外),比如在某一个C源文件内,一个被声明为静态的变量可以被该模块内的所有函数调用,但不能被模块外的函 ...
- 在C#中关于excel的导入和导出操作
一.先来看看最常见的导入操作吧! private void Import() { //打开excel选择框 OpenFileDialog frm = new OpenFileDialog(); frm ...
- listview加载性能优化
在android开发中Listview是一个很重要的组件,它以列表的形式根据数据的长自适应展示具体内容,用户可以自由的定义listview每一列的布局,但当listview有大量的数据需要加载的时候, ...
- [杂题]CSUOJ1276 Counting Route Sequence
题目链接 题意:从1号点走到n号点(每条边只能走一次, 两结点间的边数必定为奇数) 问 经过结点不同顺序的方式有多少种(如1->2->3->4和1->3->2->4 ...
- ANDROID_MARS学习笔记_S01原始版_017_绑定SERVICE
一.流程 1.编写service,重写onBind(Intent intent),返回自定义的Binder 2.自写义Binder,提供一个可访问的方法,以传递数据 3.点击界面按钮会开启servic ...
- money 和 smallmoney
代表货币或货币值的数据类型. 数据类型 范围 存储 money -922,337,203,685,477.5808 到 922,337,203,685,477.5807 8 字节 smallmoney ...