2019 cattle off more school fifth G-subsequence 1 DP

G-subsequence 1

The meaning of problems

Give you two strings \ (S, t \) , Q \ (s \) in the number of sequences can be greater than \ (t \) .

Thinking

Order \ (LEN1 \) of \ (S \) length of a sub-sequence, \ (Lent \) of \ (T \) length

  1. \ (LEN1> Lent \) : enumeration of each, if the current is not \ (0 \) then it can freely take a position behind, \ (NUM = NUM + \ K Binom {} {} LEN1, k \) is the current position to the \ (s \) remaining at the end of digits
  2. \ (LEN1 Lent = \) : violence \ (n ^ 3 \) certainly timeout, so use \ (DP \) optimization
    \ (DP [I] [J] [. 1] \) : \ (S [J] \ ) as the \ (I \) number is greater than \ (T [. 1 \) ~ \ (I] \) number prefix
    \ (DP [I] [J] [2] \) : \ (S [J] \) as the \ (I \) equal to the number \ (T [. 1 \) ~ \ (I] \) prefix number
    • \(s[j] > t[i]\)\(dp[i][j][1] = dp[i-1][1\) ~ \(j-1][1]+dp[i-1][1\) ~ \(j-1][2]\)\(dp[i][j][2] = 0\)

    • \(s[j] = t[i]\)\(dp[i][j][1] = dp[i-1][1\) ~ \(j-1]\)\(dp[i][j][2] = dp[i-1][1\) ~ \(j-1][2]\)

    • \(s[j] < t[i]\)\(dp[i][j][1] = dp[i-1][1\) ~ \(j-1]\)\(dp[i][j][2] = 0\)
  3. Maintenance with a prefix and what \ (dp [i-1] \) prefix, it can be \ (DP \) optimized to the \ (n ^ 2 \) of

AC Code

#include<bits/stdc++.h>
#define mes(a, b) memset(a, b, sizeof a)
using namespace std;
typedef long long ll;
const int maxn = 3e3+10;
const ll mod = 998244353;
struct A{
    int num[3][maxn];
    void init(){
        mes(num, 0);
    }
}a, b;
char s[maxn], t[maxn];
ll dp[maxn][maxn][3];
ll C[maxn][maxn];
void init(){    //组合数打表
    C[0][0] = C[1][0] = C[1][1] = 1;
    for(int i = 2; i < maxn;i++){
        for(int j = 0; j <= i; j++){
            C[i][j] = j==0?1:C[i-1][j-1]+C[i-1][j];
            C[i][j] %= mod;
        }
    }
}
 
int main(){
    int T, n, m;
    scanf("%d", &T);
    init();
    while(T--){
        scanf("%d%d", &n, &m);
        scanf("%s%s", s+1, t+1);
        ll ans = 0;
        a.init();   //表示dp[i-1]的前缀和
        b.init();   //表示dp[i]的前缀和
        for(int i = 1; i <= n-m; i++){
            if(s[i] != '0')
                for(int j = m; j <= n-i; j++){
                    ans = (ans + C[n-i][j])%mod;
                }
        }
        for(int i = 0; i <= n; i++){    //初始化
            a.num[2][i] = 1;        
        }
        for(int i = 1; i <= m; i++){
            for(int j = 1; j <= n; j++){
                if(s[j] > t[i]){
                    dp[i][j][1] = (a.num[1][j-1]+a.num[2][j-1])%mod;
                    dp[i][j][2] = 0;
                }
                else if(s[j] == t[i]){
                    dp[i][j][1] = a.num[1][j-1];
                    dp[i][j][2] = a.num[2][j-1];
                }
                else{
                    dp[i][j][1] = a.num[1][j-1];
                    dp[i][j][2] = 0;
                }
                b.num[1][j] = (b.num[1][j-1] + dp[i][j][1])%mod;
                b.num[2][j] = (b.num[2][j-1] + dp[i][j][2])%mod;
            }
            swap(a, b);
            b.num[1][0] = b.num[2][0] = 0;
        }
        ans = (ans + a.num[1][n])%mod;
        printf("%lld\n", ans);
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/zhuyou/p/11286010.html