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

Topic link: https: //ac.nowcoder.com/acm/contest/885/G

The meaning of problems: Given a string s, t, s request satisfies sequence number is greater than the lexicographic order of t.

Ideas: combinatorics + dp. When m is greater than the length of the sequence it is very simple, with a combination of numbers can be initialized. When a similar sequence length is equal to the number of bits m dp approach, we use dp [pos] [num] represents the number has been selected to the number of possible num The first bit s in pos.

   Then when s [pos]> t [num + 1] when:

    If you choose to s [i]: dp [pos] [num] = (dp [pos] [num] + C [n-pos] [m-num-1])% MOD;

    If not selected: dp [pos] [num] = (dp [pos] [num] + dfs (pos + 1, num))% MOD;

   ! When num = m-1 && s [pos] == t [num + 1] while (! Num = m-1 is due to avoid equal, equal only not selected):

    If you choose to s [i]: dp [pos] [num] = (dp [pos] [num] + dfs (pos + 1, num + 1))% MOD;

    If not selected: dp [pos] [num] = (dp [pos] [num] + dfs (pos + 1, num))% MOD;

   当s[pos]<t[num+1]:

    Not only is selected from: dp [pos] [num] = (dp [pos] [num] + dfs (pos + 1, num))% MOD;

AC Code:

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
 
typedef long long LL;
const int MOD=998244353;
const int maxn=3005;
 
int T,n,m;
char s[maxn],t[maxn];
LL ans,C[maxn][maxn],dp[maxn][maxn];
 
void init(){
    for(int i = 0; i < maxn;++i){
        C[i][0] = C[i][i] = 1;
        for(int j = 1; j < i;++j){
            C[i][j] = C[i-1][j] + C[i-1][j-1];
            C[i][j] %= MOD;
        }
    }
}
 
LL dfs(int pos,int num){
    if(num==m) return 1;
    if(pos>n) return 0;
    if(dp[pos][num]!=-1) return dp[pos][num];
    LL tmp=0;
    if(s[pos]>t[num+1])
        tmp=(tmp+C[n-pos][m-num-1])%MOD;
    else if(num!=m-1&&s[pos]==t[num+1])
        tmp=(tmp+dfs(pos+1,num+1))%MOD;
    if(n-pos>=m-num)
        tmp=(tmp+dfs(pos+1,num))%MOD;
    return dp[pos][num]=tmp;
}  
 
int main(){
    init();
    scanf("%d",&T);
    while(T--){
        ans=0;
        scanf("%d%d",&n,&m);
        scanf("%s",s+1);
        scanf("%s",t+1);
        for(int i=0;i<=n+1;++i)
            for(int j=0;j<=m;++j)
                dp[i][j]=-1;
        ans=(ans+dfs(1,0));
        for(int i=m+1;i<=n;++i)
            for(int j=1;j<=n-i+1;++j)
                if(s[j]!='0')
                    ans=(ans+C[n-j][i-1])%MOD;
        printf("%lld\n",ans);
    }
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/FrankChen831X/p/11284065.html