[HAOI2010] longest common subsequence - dp

Find two sequences of characters and the number of the longest common subsequence, \ (n-\ Leq 5000 \)

Solution

First question, consider \ (f [i] [j ] \) represents two strings were ran \ (i, j \) position of the longest common subsequence, then
\ [f [i] [j ] = \ max (f [i-1]
[j], f [i] [j-1], f [i-1] [j-1] + [s [i] == t [j]]) \] violence transfer to

The second question, consider \ (g [i] [j ] \) represents two strings were ran \ (i, j \) number of the longest common subsequence program position, the first statistics from normal \ (F [ ] [j], f [i i-1] [j-1] \) over the number of programs, and considering two special cases

  • If \ (f [i] [j ] = f [i-1] [j-1] \) and \ (S [I] \ NEQ T [J] \) , then the need for additional subtracting \ (g [i -1] [j-1] \ )
  • If \ (f [i] [j ] = f [i-1] [j-1] +1 \) and \ (S [I] = T [J] \) , then the need to add additional \ (G [ i-1] [j-1 ] \)
#include <bits/stdc++.h>
using namespace std;
const int mod = 100000000;
int n,m,f[2][5005],g[2][5005];
char s[5005],t[5005];

signed main() {
    cin>>s+1>>t+1;
    n=strlen(s+1);
    m=strlen(t+1);
    --n; --m;
    for(int i=0;i<=n;i++) g[0][i]=1;
    for(int i=1;i<=n;i++) {
        for(int j=1;j<=m;j++) g[i&1][j]=0;
        g[i&1][0]=1;
        for(int j=1;j<=m;j++) {
            f[i&1][j]=max(max(f[i-1&1][j],f[i&1][j-1]),
                        f[i-1&1][j-1]+(s[i]==t[j]));
            if(f[i&1][j]==f[i-1&1][j]) (g[i&1][j]+=g[i-1&1][j])%=mod;
            if(f[i&1][j]==f[i&1][j-1]) (g[i&1][j]+=g[i&1][j-1])%=mod;
            if(f[i&1][j]==f[i-1&1][j-1]&&s[i]!=t[j])
                (g[i&1][j]+=mod-g[i-1&1][j-1])%=mod;
            if(f[i&1][j]==f[i-1&1][j-1]+1&&s[i]==t[j])
                (g[i&1][j]+=g[i-1&1][j-1])%=mod;
        }
    }
    cout<<f[n&1][m]<<"\n"<<g[n&1][m]<<endl;
}

Guess you like

Origin www.cnblogs.com/mollnn/p/12390071.html