subsequnce ---- DP

サブ

問題の意味:長さ\(N- \) \(m個\)文字列\(S \) \(T \)、9桁0のストリングは、小数の組成物は、感を尋ね\(S \)より\(T \)数字列より大きな配列。

\(M \の当量のn \の当量 { 3000} \)

溶液を2つの異なるケースを考慮する:サブシーケンスの長さが等しい(T \)\より大きい配列および配列長さ\(T \)文字列。\(LEN [I] [J ] \) メンテナンス\(S \)の文字列\(Iは\)前のビット長\(J \)法的列番号(先頭のゼロなし)、その後長さよりも大きい\ (T \)数値列である(\ \ sum_ = {I}。1 + M} ^ {N-LEN [N-] [I])\

\(DP1 [I] [J ] \) メンテナンス\(S \)の文字列\(Iは\)長前にビット\(J \)よりも厳密に大きい\(T \)の前に文字列\(J \ )サブビットシーケンス番号、\(DP2である[I] [J] \)メンテナンス\(S \)の文字列\(Iは\)ビット長の前に\(J \)及び以上(T \)\文字列の前に\(J \)副ビットシーケンス番号は、それによって容易である\(S [I] \)\(T [J] \)伝達方程式の一連の大小関係を導出しました。このように等しい長さ(T \)\数字列である(DP1 [N-] [m]を\)\

コード:

#include <bits/stdc++.h>
using namespace std;
const int mod = 998244353;
char a[3005], b[3005];
int n, m;
int dp1[3005][3005], len[3005][3005], dp2[3005][3005];
int main() {
    int T;
    cin >> T;
    while(T--) {
        scanf("%d%d", &n, &m);
        int ans1 = 0, ans2 = 0;
        int maxx = max(n, m);
        for(int i = 0; i <= maxx + 2; i++) for(int j = 0; j <= maxx + 2; j++) dp1[i][j] = dp2[i][j] = 0, len[i][j] = 0;
        scanf("%s%s", a + 1, b + 1);
        dp1[0][0] = 0;
        dp2[0][0] = 1;
        len[0][0] = 1;
        for(int i = 1; i <= n; i++) {
            len[i][0] = 1;
            for(int j = 1; j <= i; j++) len[i][j] = (len[i - 1][j - 1] + len[i - 1][j]) % mod;
            if(a[i] == '0') len[i][1] = len[i - 1][1];
            dp2[i][0] = 1;
            for(int j = 1; j <= i; j++) {
                dp1[i][j] = dp1[i - 1][j];
                dp2[i][j] = dp2[i - 1][j];
                if(a[i] <= b[j]) {
                    dp1[i][j] = (dp1[i][j] + dp1[i - 1][j - 1]) % mod;
                    if(a[i] == b[j]) dp2[i][j] = (dp2[i][j] + dp2[i - 1][j - 1]) % mod;
                    else dp2[i][j] = (dp2[i][j] + dp1[i - 1][j - 1]) % mod;
                }
                if(a[i] > b[j]) {
                    dp1[i][j] = (dp1[i][j] + dp2[i - 1][j - 1]) % mod;
                    dp2[i][j] = (dp2[i][j] + dp2[i - 1][j - 1]) % mod;
                }
                //dp2[i][j] += dp1[i - 1][j - 1];
            }
        }
        for(int i = m + 1; i <= n; i++) ans1 = (ans1 + len[n][i]) % mod;
        ans2 = dp1[n][m];
        int ans = (ans1 + ans2) % mod;
        printf("%d\n", ans);
    }
    return 0;
}

おすすめ

転載: www.cnblogs.com/vege-chicken-rainstar/p/11285266.html
おすすめ