More than 2019 cattle off summer school camp (fifth) G-subsequence 1

> Portal <

Question is intended: to give you two numeric strings s, t, sequences required string string s is larger than the number t

Idea: to write his solution to a problem that is the basis dp exercises, as if indeed such a thing, since it is dp, then the definition of the status of the different transfer equation is different, not the same wording natural. Here is one for Solving dp

 

First, the digital sequence is greater than the length s of the selected string length t , certainly ok, we first enumerate the number and location with the number of combinations will be able to engage in a practice, then we get dp equal to and greater than the string length t t is the number of digits to

Set DP [i] [j] denotes the front i-s, prior to the j-th matching the number of kinds of t

  • if (s [i] == t [j]) dp [i] [j] = dp [i -1] [j] + dp [i - 1] [j - 1]; // add equal, then equal to and the addition is not added
  • if (s [i] <t [j]) dp [i] [j] = dp [i - 1] [j]; // do not less than enumerated, then, will be less than equal length, while negative leading zeros
  • if (s [i]> s [j]) ans + = dp [i - 1] [j - 1] * C [n - i] [m - j]. // front matching j-1 type number * later a pick len2-j, must be greater than equal to the length is greater than the

Finally, note that the string length is greater than the number t calculated excluding leading zeroes can be a
Code

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod = 998244353;
const int maxn = 3010;

int n, m;
ll f[maxn][maxn], dp[maxn][maxn];
char s[maxn], t[maxn];
void pre()
{
    f[1][1] = f[1][0] = f[0][0] = 1;
    for (int i = 2; i <= 3000; i++){ 
        f[i][0] = 1;
        for (int j = 1; j <= i; j++) f[i][j] = (f[i-1][j-1]+f[i-1][j])%mod;
    }
}

int main() 
{
    pre();
    int T;
    scanf("%d", &T);
    while(T--) {
        scanf("%d %d", &n, &m);
        scanf("S% S% " , S + . 1 , T + . 1 );
         for ( int I = 0 ; I <= n-; I ++ ) 
            DP [I] [ 0 ] = . 1 ; 
            
        LL ANS = 0 ;
         // select the current digit equal to t sequence 
        for ( int I = . 1 ; I <= n-; I ++ )
             for ( int J = . 1 ; J <= min (m, I); J ++ ) { 
                DP [I] [J] = DP [I- . 1 ] [J]; // S [I] <where t [j] is 
                if(S [I] == T [J]) DP [I] [J] = (DP [I] [J] + DP [I- . 1 ] [J- . 1 ])% MOD;
                 IF (S [I] > t [J]) = ANS (ANS + DP [I- . 1 ] [J- . 1 ] * F [Ni] [MJ])% MOD; 
            } 
        // select the current amount is greater than t, the sequence   
        for ( int I = . 1 ; I <= n-; I ++ ) {
             IF (S [I] == ' 0 ' ) Continue ;
             for ( int J = m; J <= Ni; J ++ ) 
                ANS = (ANS + F [Ni] [J] )% MOD; // I is an enumeration of the first number, j is taken several enumerated later
        }
        printf("%lld\n", ans);
    }
    return 0;
}
View Code

 

Guess you like

Origin www.cnblogs.com/wizarderror/p/11307389.html