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了,如下为代码:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <numeric> 6 using namespace std; 7 typedef long long ll; 8 const int M=1e3+10; 9 int n; 10 int a[M],b[M]; 11 int ans=1; 12 13 int dfs(int x,int y) { 14 int t=0; 15 if(y>n||x>n) { 16 return t; 17 } else if(a[x]==b[y]) { 18 t=1+dfs(x+1,y+1); 19 } else { 20 int t1=dfs(x,y+1); 21 int t2=dfs(x+1,y); 22 t=max(t1,t2); 23 } 24 25 ans=max(ans,t); 26 return t; 27 28 } 29 /* 30 6 31 5 3 1 4 2 6 32 1 5 3 2 4 6 33 */ 34 int main() { 35 scanf("%d",&n); 36 for(int i=1; i<=n; i++)scanf("%d",&a[i]); 37 for(int i=1; i<=n; i++)scanf("%d",&b[i]); 38 dfs(1,1); 39 printf("%d ",ans); 40 return 0; 41 42 43 44 }
改了一下,写成动态规划,将原本dfs(i,j)改写成dp【i】【j】存起来
i ,j,表示当前序列 — a,b,分别在哪个位置,dp【i】【j】表示在这一状态下,a1-- ai 与 b1-- bj,存在最大公共子序列的长度
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <numeric> 6 using namespace std; 7 typedef long long ll; 8 const int M=1e3+10; 9 int n; 10 int a[M],b[M]; 11 int ans=1; 12 int dp[M][M]; 13 /* 14 int dfs1(int x,int y) { 15 int t=0; 16 if(y>n||x>n) { 17 return t; 18 } else if(a[x]==b[y]) { 19 t=1+dfs(x+1,y+1); 20 } else { 21 int t1=dfs(x,y+1); 22 int t2=dfs(x+1,y); 23 t=max(t1,t2); 24 } 25 26 ans=max(ans,t); 27 return t; 28 29 } 30 31 32 int dfs(int x,int y) { 33 int t=0; 34 if(y<1||x<1) { 35 return t; 36 } else if(a[x]==b[y]) { 37 t=1+dfs(x-1,y-1); 38 } else { 39 int t1=dfs(x,y-1); 40 int t2=dfs(x-1,y); 41 t=max(t1,t2); 42 } 43 44 ans=max(ans,t); 45 return t; 46 47 }*/ 48 /* 49 6 50 5 3 1 4 2 6 51 1 5 3 2 4 6 52 */ 53 void f() { 54 int i,j; 55 memset(dp,0,sizeof(dp)); 56 57 for( i=1; i<=n; i++) { 58 for( j=1; j<=n; j++) { 59 if(a[i]==b[j]) { 60 dp[i][j]=dp[i-1][j-1]+1; 61 } else { 62 dp[i][j]=max(dp[i-1][j],dp[i][j-1]); 63 } 64 } 65 } 66 printf("%d ",dp[n][n]); 67 68 } 69 70 71 int main() { 72 scanf("%d",&n); 73 for(int i=1; i<=n; i++)scanf("%d",&a[i]); 74 for(int i=1; i<=n; i++)scanf("%d",&b[i]); 75 f(); 76 // int n1=n; 77 //dfs(n1,n1); 78 //printf("%d ",ans); 79 return 0; 80 81 82 83 }
(AC代码)