newcoder 练习赛17 B 好位置 dp 最长公共子序列
Posted vainglory
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了newcoder 练习赛17 B 好位置 dp 最长公共子序列相关的知识,希望对你有一定的参考价值。
链接:https://www.nowcoder.com/acm/contest/109/B
来源:牛客网
好位置
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld
题目描述
给出两个串s和x
定义s中的某一位i为好的位置,当且仅当存在s的子序列 满足y=x且存在j使得i=kj成立。
问s中是否所有的位置都是好的位置。
定义s中的某一位i为好的位置,当且仅当存在s的子序列 满足y=x且存在j使得i=kj成立。
问s中是否所有的位置都是好的位置。
输入描述:
一行两个字符串s,x,这两个串均由小写字母构成。
1 <= |s|, |x| <= 200000
输出描述:
Yes表示是。
No表示不是。
示例1
输入
abab ab
输出
Yes
示例2
输入
abacaba aba
输出
No
示例3
输入
abc ba
输出
No
思路:dp[i]代表s前i个字符(包含第i个字符)所能匹配到e的最长位置
注意递推方程:如果s[i]==e[j] dp[i]=j;
else dp[i]等于用该位置去替代(1,j)中最大的那一个字符与s[i]相等的位置,同时保证了最长公共序列
相当于在s的子序列里查找e串 ,66666666
#include<bits/stdc++.h> using namespace std; const int N=2e5+10; int dp[N][2]; string a,b; vector<int>pos[26]; int main(){ std::ios::sync_with_stdio(false); while(cin>>a>>b){ int l1=a.size(),l2=b.size(); for(int i=0;i<l2;i++) pos[b[i]-‘a‘].push_back(i); int j=0; for(int i=0;i<l1;i++){ if(a[i]==b[j]) j++; else{ int t=a[i]-‘a‘; int tt=lower_bound(pos[t].begin(),pos[t].end(),j)-pos[t].begin()-1; j=tt+1; } dp[i][0]=j; } j=0; reverse(a.begin(),a.end()); reverse(b.begin(),b.end()); for(int i=0;i<=25;i++) pos[i].clear(); for(int i=0;i<l2;i++) pos[b[i]-‘a‘].push_back(i); for(int i=0;i<l1;i++){ if(a[i]==b[j]) j++; else{ int t=a[i]-‘a‘; int tt=lower_bound(pos[t].begin(),pos[t].end(),j)-pos[t].begin()-1; j=tt+1; } dp[i][1]=j; } int flag=1; for(int i=0;i<l1;i++){ if(dp[i][0]+dp[l1-1-i][1]<l2) {flag=0;break;} } if(flag) cout<<"Yes"<<"\n"; else cout<<"No"<<"\n"; } return 0; }
以上是关于newcoder 练习赛17 B 好位置 dp 最长公共子序列的主要内容,如果未能解决你的问题,请参考以下文章
newcoder 79F 小H和圣诞树 换根 DP + 根号分治
bzoj 4990 [USACO17FEB] Why Did the Cow Cross the Road II P (树状数组优化DP)