【CF1204E]ナターシャ、サーシャとプレフィックス和题解

序文

本明細書の構成は、構成におけるm、nが1の配列を指す-1。
Tucaoないような長いタイトルが、これは確かに良い質問です。

問題の解決策

DPのタイトル・ワードは、直接状態/変数/転送を言っていません。

状態

私たちは、fは、「最大の接頭語合計」の合計を表し定義します

変数

F [i] [j]は、J-1番目の "最大プレフィックス和" 和、I-1であります

転移

私たちは、[i]をする[J] Cの点に注意してください\(\左(\ I}始めるマトリックス{\\ J \行列のエンド{} \右)\) :、その後、
\ [F [I] [J] = \左\ {\} {行列を始めるF [ I-1] [j]は、時刻C \ +1 [iが+ J-1] [I-1] \\ F [I] [J-1] +( - 1)\回(C [iは+ 1-J] [-J 1] -k [I] [-J 1])\マトリックス終了{}右\は\]
K [i] [j]はJ番目、I-1を表します最大プレフィックス-1と0の数が同じように配置された
後、式はそれを起動する方法ですか?
私たちはしっかりたびに新しい番号が追加されていることを信じていたときに、まだ規制はすべての順列が柯エネルギーを移動カバーすることを保証するために設定されている挿入配列の最前線の数。
我々は挿入した場合、関係なく、以前の配列アラインメントの、最大プレフィクス和は1に追加され、1であるので、私1オン1、J -1配列に対応する(左\(\ \開始{行列} I + J-1 \\ iは端{\行列を} \右)\) 置換法、現在の状態の増加に寄与\(\左(\ {始まる行列を} iがJ-1 \\を+ Iが端{行列} \ \右)\)
私たちはこのような状況では、-1で挿入した場合とまったく同じですが、独自の「最大プレフィックス和」の配列がある場合は0である、そして我々は貢献それ(最大プレフィックス」ために含めるべきではないことに注意合計)0「最小ので、減算K [i]は[J]。
どうやら組み合わせの柯の数がパスカルの三角形の再発により解決します。
だから今、私たちの問題は、何をすべきかというK [i] [j]はあります。
私たちは、最初の[i]の[j]の再帰式をKを与えます。
\ [K [i]は[J ] = \左\ {\開始{行列} i = 0&K [i]は[J] = 1 \\ J = 0&K [i]は[J] = 0 \\ I > J&K [i]は[ J] = 0 \\ \テキスト{ 残りケース}&K [i]は[J ] = K [I-1]〜[J] + K [i]は[J-1] \端右\ {マトリックスは}。\]
この再帰Keが少し不明瞭であることができるが、これを理解する簡単な方法は、外向きの状態遷移の方程式を見つけることであり、次いで上記の式に変換します。
だから我々はこの問題を解決しました。

コード

いいえカードは、多くの場合、私を許していません。

#include <cstdio>
#define MOD 998244853

long long f[2005][2005];
long long k[2005][2005];
long long C[4005][4005];

int main(){
    int n, m; scanf("%d %d", &n, &m);
    for (register int i = 0; i <= n; ++i)
        for (register int j = 0; j <= m; ++j){
            if (i == 0) k[i][j] = 1;
            else if (j == 0) k[i][j] = 0;
            else if (i > j) k[i][j] = 0;
            else k[i][j] = (k[i - 1][j] + k[i][j - 1]) % MOD;
        }
    C[0][0] = C[1][0] = C[1][1] = 1;
    for (register int i = 2; i <= n + m; ++i){
        C[i][0] = 1;
        for (register int j = 1; j <= i; ++j)
            C[i][j] = (C[i - 1][j] + C[i - 1][j - 1]) % MOD;
    }
    for (register int i = 0; i <= n; ++i)
        f[i][0] = i, f[0][i] = 0;
    for (register int i = 1; i <= n; ++i)
        for (register int j = 1; j <= m; ++j)
            f[i][j] = ((f[i - 1][j] + C[i + j - 1][i - 1]) % MOD + (f[i][j - 1] - C[i + j - 1][j - 1] + k[i][j - 1] + MOD) % MOD) % MOD;
    printf("%I64d", f[n][m]);
    return 0;
}

おすすめ

転載: www.cnblogs.com/linzhengmin/p/11391922.html