YbtOJ#20235-[冲刺NOIP2020模拟赛Day9]公共序列【dp】
生活随笔
收集整理的這篇文章主要介紹了
YbtOJ#20235-[冲刺NOIP2020模拟赛Day9]公共序列【dp】
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
正題
題目鏈接:https://www.ybtoj.com.cn/contest/66/problem/3
題目大意
給出兩個字符串A,BA,BA,B,求它們的最長公共子序列。
解題思路
先考慮樸素的dpdpdp,設fi,jf_{i,j}fi,j?表示到AAA的第iii個,BBB的第jjj個時候的最長公共子序列長度。
發(fā)現(xiàn)這樣的dpdpdp由于A的長度很大,B的長度很小,所以導致dpdpdp里的數(shù)值很小,轉移卻十分冗長。發(fā)現(xiàn)還有一種最優(yōu)的狀態(tài)表示法,當匹配到BBB的相同位置且當且公共長度相同時顯然在AAA的位置越前越好。那么可以設fi,jf_{i,j}fi,j?表示匹配到BBB的第iii個時,目前公共長度為jjj的在AAA中最前的位置。
時間復雜度O(26n+m2)O(26n+m^2)O(26n+m2)
codecodecode
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N=1e6+10,M=1100; int n,m,last[26],nxt[N][26],f[M][M]; char a[N],b[M]; int main() {freopen("lcs.in","r",stdin);freopen("lcs.out","w",stdout);scanf("%s",a+1);n=strlen(a+1);scanf("%s",b+1);m=strlen(b+1);for(int i=n;i>=0;i--){for(int j=0;j<26;j++)nxt[i][j]=last[j];if(i)last[a[i]-'a']=i;}memset(f,0x3f,sizeof(f));f[0][0]=0;for(int i=1;i<=m;i++){for(int j=0;j<=i;j++){if(j&&f[i-1][j-1]<=n&&nxt[f[i-1][j-1]][b[i]-'a'])f[i][j]=min(f[i][j],nxt[f[i-1][j-1]][b[i]-'a']);f[i][j]=min(f[i][j],f[i-1][j]);}}for(int i=m;i>=0;i--)if(f[m][i]<2147483647/3)return printf("%d\n",i);return 0; } 創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎總結
以上是生活随笔為你收集整理的YbtOJ#20235-[冲刺NOIP2020模拟赛Day9]公共序列【dp】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 葛优个人资料 演员葛优介绍
- 下一篇: YbtOJ#20236-[冲刺NOIP2