caioj 1069 动态规划入门(二维一边推2:顺序对齐)(最长公共子序列拓展总结)
caioj 1068是最长公共子序列裸体,秒过, 就不写博客了
caioj 1069到1071 都是最长公共字序列的拓展,我总结出了一个模型,屡试不爽
(1) 字符串下标从1开始,因为0用来表示字符为空的情况,而不是第一个字符
(2)初始化问题。
一般设f[i][j]为第一个字符前i个,第二个字符前j个的最优价值
f[0][0] = 0
然后要初始化f[i][0], f[0][i]
这个时候要根据题意。
这个时候就是一个字符有,一个字符空的情况
(3)然后就可以两层for了
这个时候记住根据题目有不同的决策,取最优
一般有匹配字符和不匹配字符(如加空格)两种情况
按照题目而定
最后要注意如果是取min初值要最大,max初值最小
或者直接用其中一个决策作为初值
这道题要右对齐,所以直接逆序存
然后套模型
初始化的话,显然空的时候全部都是空格
所以都初始化为-1
决策的话
如果是匹配字符的话,一样就加2,否则不加
如果是空格的话,就两边枚举空格长度取最优
具体看代码
#include<cstdio>
#include<cstring>
#include<algorithm>
#define REP(i, a, b) for(int i = (a); i < (b); i++)
using namespace std;
const int MAXN = 60;
char a[MAXN], b[MAXN], s[MAXN];
int f[MAXN][MAXN];
void up(int &x, int a) { x = max(x, a); }
int main()
{
scanf("%s", s + 1);
int lena = strlen(s + 1);
REP(i, 1, lena + 1) a[i] = s[lena-i+1];
scanf("%s", s + 1);
int lenb = strlen(s + 1);
REP(i, 1, lenb + 1) b[i] = s[lenb-i+1];
REP(i, 1, lena + 1) f[i][0] = -1;
REP(i, 1, lenb + 1) f[0][i] = -1;
f[0][0] = 0;
int ans = -1e9;
REP(i, 1, lena + 1)
REP(j, 1, lenb + 1)
{
f[i][j] = -1e9;
if(a[i] == b[j]) up(f[i][j], f[i-1][j-1] + 2); //选择匹配字符
else up(f[i][j], f[i-1][j-1]);
for(int k = i - 1; k >= 0; k--) up(f[i][j], f[k][j] - 1); //选择空格
for(int k = j - 1; k >= 0; k--) up(f[i][j], f[i][k] - 1);
up(ans, f[i][j]);
}
printf("%d\n", ans);
return 0;
}
caioj 1069 动态规划入门(二维一边推2:顺序对齐)(最长公共子序列拓展总结)的更多相关文章
- caioj 1071 动态规划入门(二维一边推4:相似基因) (最长公共子序列拓展)
复制上一题总结 caioj 1069到1071 都是最长公共字序列的拓展,我总结出了一个模型,屡试不爽 (1) 字符串下标从1开始,因为0用来表示字符为空的情况,而不是第一个字符 (2) ...
- caioj 1070 动态规划入门(二维一边推3:字符距离)(最长公共子序列拓展)
复制上一题总结 caioj 1069到1071 都是最长公共字序列的拓展,我总结出了一个模型,屡试不爽 (1) 字符串下标从1开始,因为0用来表示字符为空的情况,而不是第一个字符 (2) ...
- caioj 1073 动态规划入门(三维一边推:最长公共子序列加强版(三串LCS))
三维的与二维大同小异,看代码. #include<cstdio> #include<cstring> #include<algorithm> #define REP ...
- caioj 1063 动态规划入门(一维一边推1:美元和马克)
这道题一开始我是这么想的 最后的答案肯定是某次的马克换回来的,但这个该怎么确定?? 实际上应该把范围缩小,只看最后一次和倒数第二次之间有什么联系. 可以发现,只有两种可能,最后一天换或者不换.换的话就 ...
- caioj 1067动态规划入门(一维一边推5: 乘积最大(高精度版))
因为这里涉及到乘号的个数,那么我们可以用f[i][j]表示前i个位乘号为j个时的最大乘积 那么相比上一题就是多了一层枚举多少个乘号的循环,可以得出 f[i][r] = max(f[j - 1][r - ...
- caioj 1066 动态规划入门(一维一边推4:护卫队)(分组型dp总结)
很容易想到f[i]为前i项的最优价值,但是我一直在纠结如果重量满了该怎么办. 正解有点枚举的味道. 就是枚举当前这辆车与这辆车以前的组合一组,在能组的里面取最优的. 然后要记得初始化,因为有min,所 ...
- caioj 1065 动态规划入门(一维一边推3:合唱队形)
就是最长上升子序列,但是要用n^2的算法. #include<cstdio> #include<algorithm> #define REP(i, a, b) for(int ...
- C++动态规划实现查找最长公共子序列
问题描述: 给定两个序列X={x1,x2,…,xm}和Y={y1,y2,…,yn},找出X和Y的最长公共子序列.(给定两个序列X和Y,当另一序列Z既是X的子序列又是Y的子序列时,称Z是序列X和Y的公共 ...
- 动态规划小结 - 二维动态规划 - 时间复杂度 O(n*n)的棋盘型,题 [LeetCode] Minimum Path Sum,Unique Paths II,Edit Distance
引言 二维动态规划中最常见的是棋盘型二维动态规划. 即 func(i, j) 往往只和 func(i-1, j-1), func(i-1, j) 以及 func(i, j-1) 有关 这种情况下,时间 ...
随机推荐
- 从SQL注入谈数据访问层
什么是SQL注入? SQL注入就是应用程序的开发人员未预期的吧SQL语句传入到应用程序的过程,如果直接使用用户输入的值来构建SQL语句的应用程序是很可能会受到SQL注入攻击的.特别是基于浏览器的网络应 ...
- Android ViewPager+属性动画 实现炫酷视差动画效果
ViewPager有一个setPageTransform()方法可以实现很多酷炫的动画效果 先来个仿QQ的侧滑面板效果 vp.setPageTransformer(true, new PageTran ...
- (转载)Android:学习AIDL,这一篇文章就够了(上)
前言 在决定用这个标题之前甚是忐忑,主要是担心自己对AIDL的理解不够深入,到时候大家看了之后说——你这是什么玩意儿,就这么点东西就敢说够了?简直是坐井观天不知所谓——那样就很尴尬了.不过又转念一想, ...
- 如何把非服务程序(一般的应用程序)注册为Windows服务
非服务程序:不是标准的服务形式的程序吧,只是普通的应用程序. 1.要实现这个功能要用到微软提供的两个小工具“instsrv.exe”和“srvany.exe”,工具可以从微软下载安装工具包得到:htt ...
- POJ 2481 Cows【树状数组】
题意:给出n头牛的s,e 如果有两头牛,现在si <= sj && ei >= ej 那么称牛i比牛j强壮 然后问每头牛都有几头牛比它强壮 先按照s从小到大排序,然后用e来 ...
- 在Scrapy中如何利用Xpath选择器从HTML中提取目标信息(两种方式)
前一阵子我们介绍了如何启动Scrapy项目以及关于Scrapy爬虫的一些小技巧介绍,没来得及上车的小伙伴可以戳这些文章: 手把手教你如何新建scrapy爬虫框架的第一个项目(上) 手把手教你如何新建s ...
- python继承 super()
写这篇博文,始于以下问题的探究: #coding:utf-8 class A(object): def __init__(self): print 'enter A' print 'leave A' ...
- dedecmsV5.7自定义图片字段调用方法
正常情况下,在列表页(也就是 {dede:list}标签)调用附加的图片类型字段则会出现Fatal error: Call to a member function GetInnerText() on ...
- 【Computer Vision】角点检测和匹配——Harris算子
一.基本概念 角点corner:可以将角点看做两个边缘的交叉处,在两个方向上都有较大的变化.具体可由下图中分辨出来: 兴趣点interest point:兴趣点是图像中能够较鲁棒的检测出来的点,它不仅 ...
- 虚拟集群LVS及DR模式搭建笔记
LVS(虚拟集群Linux Virtual Server) LVS-NAT:地址转换,数据包来回都要经过NAT转换,所以Director Server(即LVS服务器)将成为系统瓶颈.使用NAT模式将 ...