D: 魔法少女资格面试

题目描述

众所周知,魔法少女是一个低危高薪职业。随着近年来报考魔法少女的孩子们越来越多,魔法少女行业已经出现饱和现象!
为了缓和魔法少女界的就业压力,魔法少女考核员丁丁妹决定增加魔法少女资质考核的难度。
然而,即使如此,通过资质考核的魔法少女们数量仍然过多,因此,丁丁妹决心增加一轮面试,从而淘汰掉更多的预备魔法少女。
具体而言,她打算对所有面试者询问这样一个问题:
给两个长度为

n

的全排列,它们的最长公共子序列长度是多少?
不幸的是,由于丁丁妹没有好好上过学,她自己也不知道答案是多少,因此她使用魔法找到了你,希望你来帮她解决这个问题。

输入描述

每个测试点仅有一组数据。
第一行是一个正整数

n

,表示全排列长度。
第二行有

n

个整数,保证是一个

n

的全排列。
第三行有

n

个整数,保证是一个

n

的全排列。
其中,保证

1

n

1000

输出描述

输出一行一个整数,表示两数组的最长公共子序列长度。

样例输入

5
1 3 2 4 5
5 2 3 1 4

样例输出

2

Hint

如果你愿意思考

1

n

1000000

时的解法,那么丁丁妹会很高兴地录取你。

题解思路

这道题思路比较明显的,关系式就是:

也可以从后往前写成

L(i,j)=L(i+1,j+1)取等

L(i,j)=max(L(i,j+1),L(i+1,j))不等

但是这个式子我用递归直接写,就给TE了,如下为代码:

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <numeric>
using namespace std;
typedef long long ll;
const int M=1e3+;
int n;
int a[M],b[M];
int ans=; int dfs(int x,int y) {
int t=;
if(y>n||x>n) {
return t;
} else if(a[x]==b[y]) {
t=+dfs(x+,y+);
} else {
int t1=dfs(x,y+);
int t2=dfs(x+,y);
t=max(t1,t2);
} ans=max(ans,t);
return t; }
/*
6
5 3 1 4 2 6
1 5 3 2 4 6
*/
int main() {
scanf("%d",&n);
for(int i=; i<=n; i++)scanf("%d",&a[i]);
for(int i=; i<=n; i++)scanf("%d",&b[i]);
dfs(,);
printf("%d\n",ans);
return ; }

改了一下,写成动态规划,将原本dfs(i,j)改写成dp【i】【j】存起来

i  ,j,表示当前序列 — a,b,分别在哪个位置,dp【i】【j】表示在这一状态下,a1-- ai 与 b1-- bj,存在最大公共子序列的长度

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <numeric>
using namespace std;
typedef long long ll;
const int M=1e3+;
int n;
int a[M],b[M];
int ans=;
int dp[M][M];
/*
int dfs1(int x,int y) {
int t=0;
if(y>n||x>n) {
return t;
} else if(a[x]==b[y]) {
t=1+dfs(x+1,y+1);
} else {
int t1=dfs(x,y+1);
int t2=dfs(x+1,y);
t=max(t1,t2);
} ans=max(ans,t);
return t; } int dfs(int x,int y) {
int t=0;
if(y<1||x<1) {
return t;
} else if(a[x]==b[y]) {
t=1+dfs(x-1,y-1);
} else {
int t1=dfs(x,y-1);
int t2=dfs(x-1,y);
t=max(t1,t2);
} ans=max(ans,t);
return t; }*/
/*
6
5 3 1 4 2 6
1 5 3 2 4 6
*/
void f() {
int i,j;
memset(dp,,sizeof(dp)); for( i=; i<=n; i++) {
for( j=; j<=n; j++) {
if(a[i]==b[j]) {
dp[i][j]=dp[i-][j-]+;
} else {
dp[i][j]=max(dp[i-][j],dp[i][j-]);
}
}
}
printf("%d\n",dp[n][n]); } int main() {
scanf("%d",&n);
for(int i=; i<=n; i++)scanf("%d",&a[i]);
for(int i=; i<=n; i++)scanf("%d",&b[i]);
f();
// int n1=n;
//dfs(n1,n1);
//printf("%d\n",ans);
return ; }

(AC代码)

动态规划_基础_最长公共子序列_多种方法_递归/dp的更多相关文章

  1. 动态规划(一)——最长公共子序列和最长公共子串

    注: 最长公共子序列采用动态规划解决,由于子问题重叠,故采用数组缓存结果,保存最佳取值方向.输出结果时,则自顶向下建立二叉树,自底向上输出,则这过程中没有分叉路,结果唯一. 最长公共子串采用参考串方式 ...

  2. 动态规划模板2|LCS最长公共子序列

    LCS最长公共子序列 模板代码: #include <iostream> #include <string.h> #include <string> using n ...

  3. 对最长公共子序列(LCS)等一系列DP问题的研究

    LIS问题: 设\(f[i]\)为以\(a[i]\)结尾的最长上升子序列长度,有: \[f[i]=f[j]+1(j<i&&a[j]<a[i])\] 可以用树状数组优化至\( ...

  4. 动态规划----最长公共子序列(LCS)问题

    题目: 求解两个字符串的最长公共子序列.如 AB34C 和 A1BC2   则最长公共子序列为 ABC. 思路分析:可以用dfs深搜,这里使用到了前面没有见到过的双重循环递归.也可以使用动态规划,在建 ...

  5. 动态规划 - 最长公共子序列(LCS)

    最长公共子序列也是动态规划中的一个经典问题. 有两个字符串 S1 和 S2,求一个最长公共子串,即求字符串 S3,它同时为 S1 和 S2 的子串,且要求它的长度最长,并确定这个长度.这个问题被我们称 ...

  6. 动态规划——最长公共子序列LCS及模板

    摘自 https://www.cnblogs.com/hapjin/p/5572483.html 这位大佬写的对理解DP也很有帮助,我就直接摘抄过来了,代码部分来自我做过的题 一,问题描述 给定两个字 ...

  7. [Python]最长公共子序列 VS 最长公共子串[动态规划]

    前言 由于原微软开源的基于古老的perl语言的Rouge依赖环境实在难以搭建,遂跟着Rouge论文的描述自行实现. Rouge存在N.L.S.W.SU等几大子评估指标.在复现Rouge-L的函数时,便 ...

  8. 最长公共子序列lcs 51nod1006

    推荐参考博客:动态规划基础篇之最长公共子序列问题 - CSDN博客  https://blog.csdn.net/lz161530245/article/details/76943991 个人觉得上面 ...

  9. HDU 1159 Common Subsequence --- DP入门之最长公共子序列

    题目链接 基础的最长公共子序列 #include <bits/stdc++.h> using namespace std; ; char c[maxn],d[maxn]; int dp[m ...

  10. 最长公共子序列python实现

    最长公共子序列是动态规划基本题目,以下依照动态规划基本步骤解出来. 1.找出最优解的性质,并刻划其结构特征 序列a共同拥有m个元素,序列b共同拥有n个元素,假设a[m-1]==b[n-1],那么a[: ...

随机推荐

  1. [剑指offer]25.合并两个排序的链表(迭代+递归)

    25.合并两个排序的链表 题目 输入两个递增排序的链表,合并这两个链表并使新链表中的节点仍然是递增排序的. 示例1: 输入:1->2->4, 1->3->4 输出:1-> ...

  2. 使用toString()检测对象类型

    可以通过toString() 来获取每个对象的类型.为了每个对象都能通过 Object.prototype.toString() 来检测,需要以 Function.prototype.call() 或 ...

  3. 【前端词典】这些功能其实不需要 JS,CSS 就能搞定

    前言 今天我们大家介绍一些你可能乍一眼以为一定需要 JavaScript 才能完成的功能,其实 CSS 就能完成,甚至更加简单. 内容已经发布在 gitHub 了,欢迎围观 Star,更多文章都在 g ...

  4. iphone ios app互相调用

    正好要做这个,记录一下 1.ios应用程序间互相启动 2.网页如何调用自己的app http://www.dotblogs.com.tw/yang5664/archive/2012/11/24/850 ...

  5. Python第六章-函数04-递归函数和拉姆达表达式

    五.递归函数 什么叫递归(recusive)? 你拿两个镜子互相面对着, 然后去看镜子, 会发现每个镜子中很多个镜子, 层层的嵌套, 无穷尽, 这就是一种递归! 从前有坐山, 山里有座庙, 庙里有个老 ...

  6. coding++: java把一个整数拆分为单个值

    方式一: int num = 100; int[] ary = new int[(num+"").length()]; for(int i = ary.length-1;i> ...

  7. [POJ2533]Longest Ordered Subsequence<dp>

    题目链接:http://poj.org/problem?id=2533 描述: A numeric sequence of ai is ordered if a1 < a2 < ... & ...

  8. Java面试金典

    1,将构造函数声明为私有的作用 构造函数私有化,保证类以外的地方不能直接实例化该类,这种情况下,要创建这个类的实例,只能提供一个公共静态方法,像工厂方法模式,由于构造函数私有化,不能被继承. 2,在t ...

  9. 记一次Task抛异常,调用线程处理而引发的一些随想

    记一次Task抛异常,调用线程处理而引发的一些随想 多线程调用,任务线程抛出异常如何在另一个线程(调用线程)中捕获并进行处理的问题. 1.任务线程在任务线程执行语句上抛出异常. 例如: private ...

  10. Mybatis中的# 与 $

    我们说MyBatis有两种注入参数的方式, - 一种是#{} - 另一种是${} 这两种从使用功能来看差距不大,那为什么会强推使用#? ${}使用的是拼接字符串,#{}使用的是占位符的方法,经过了处理 ...