P5664衛宮家族の食事今日
クライQAQ 12345678日のこの全体の問題は、問題と解決策のブログSYをされ、タイトルの助けを借りて完成QAQ
問題の解決策
問題の意味を簡素化
> N * M、Kの合計が選択され、選択することができない、要求の行列を与えます。
1.各行は一つだけを選択することができます
各列まで選択2. Aを
法律上のプログラムの数を計算
そのようなAの事であるものの抽象理解
解決のアイデア
Moは考えていた直接の解決策、それは、我々は困難であるが、逆検討している違法なスキームの数-プログラムの総数は、
私たちは簡単に取ることができ、制限はありません考えてみましょう、しかし、このスキームの中でいくつかの1に満足していないがあり、2はまた、いくつかを満たしていない、どちらもそこに満足しないでも1〜2を満足しています
私たちは、ある要件1を満たすことを望む、我々は唯一の1行に1つずつ選び、その後、我々は数2を満たしていないプログラムの要件を満たすの前提を削除します
それは次のとおりです。
総プログラム - 2つのプログラムを1が、数(不正プログラムの数)を満たす満たさない - 不正スキームの数= 1のプログラムの合計数を満たします
解決プロセス
1.どのようにオンデマンドプログラム番号1を満たすために???
セット配列TOT [i] [j]は、フロントI j番目の行がプログラムの最大数から選択され、意味します
SUM [i]を表し、i番目の行の総数
現在のi行目の各桁が選択または選択されていないことができるため、選挙は(実際には、乗算分布の原則)新しいスキームを形成しなければならなかったの前に、再帰式を取得します、すべての選挙を考えてみます。
すべて[I] [J] =すべての[I-1]〜[J] +すべての[I-1] [J-1] *和[I]
2.どのように違法なスキームを求めて多くの???
それは違法である要件2を満たしていない、以上の各列1
複数の実際の数の唯一一つ> =つ以上存在する場合ため
ヶ月、その後総数は、矛盾があった場合> Kに選択
だから、列挙違法列を考慮することができます
我々は、選択された現在の列挙の不正列設定 j個 目の、合計残りの列は、選択した K番目
wron [I] [J] [ k]の最初に現在の列挙を表すI 行、列選択不法 jは ヶ月、残りの列は、合計選択 k個の新しい列、または列にプログラムの数、それぞれの列挙をない選択、またはいずれか、合法的にこの列を選択していない残りの列のいずれかを選択し、再帰式を得ます:
カラス[I] [J] [K] =カラス[I-1]〜[J] [K]
+ wron [I-1] [J + 1] [K]・[I] [行]
+ wron [I-1] [j]を[K + 1] *(和[1] - [I] [行])
私たちは、実際には気にしない jは 、k個の 残り、その後、不法な列がX + j個目を選択し、我々は複数の選択肢のj番目の列の残りの部分よりも違法列を設定し、我々だけうまくそれらの相対的な大きさを知っている必要があり、特定の値をX選挙での列の数は、我々は読み取り専用に再帰式のように列挙jに必要があります。
wron [I] [J] = wron [I-1]〜[J]
+ wron [I-1] [J-1] * [I] [ライン]
+ wron [I-1] [J + 1] *(和[1] - [I] [行])
実際には、jの範囲であり、i行目の複数の選択肢以外のほとんどの違法列は、以下の選択肢が他よりもアップi行目にされることに注意して、 [-i、i]は 、配列のインデックスが負ではないので、我々は考えます統一インデックスnを追加、J列挙範囲は[NI、N + I]
そのJ> 0、マイナスのようなプログラムの総数は違法なスキームのその後数
以下のように最後に、ノート剰余
コード
書式#include <iostreamの> の#include <cstdioを> する#include <cstdlib> 書式#include <アルゴリズム> 書式#include <cmath> の#include <キュー> の#include < 文字列 > の#include <CStringの> 使用して 名前空間はstdを、 typedefの長い 長いLL。 インライン読み取り()っ { LL ANS = 0 。 チャー最後=を' '、CH = GETCHAR()。 しばらく(CH < ' 0 ' || CH> ")最後= CH、CH = GETCHAR()。 一方、(CH> = ' 0 ' && CH <= ' 9 ')ANS = ANS * 10 + CH- ' 0 '、CH = GETCHAR()。 もし(最後== ' - ')ANS = - ANS; 戻り値は、ANS; } CONST INT MOD = 998244353 。 整数N、M。 ちゃう[ 105 ] [ 2005 ]。 LL和[ 105 ]。 LL TOT [ 105 ] [ 2005 ]。 のLL wron [ 105 ] [ 400 ]。 LL ANS = 0 。 INT )(主 { N読み取り=(); M =は(読み取り) 以下のために(INT iが= 1 ; I <= N; I ++ ) のための(INT J = 1 ; J <= Mであり、j ++ ){ [I] [J] = )(読み取ります。 和[I] =(SUM [I] + [I] [J])%のMOD。 } TOT [ 0 ] [ 0 ] = 1 ; 以下のための(int型 I = 1; I <= N; I ++) のための(INT J = 0 ; J <= N; J ++ ) TOT [I] [J] =((TOT [I- 1 ] [j]は%MOD + TOT [I- 1 ] [J- 1 ] *和[I]%のMOD)%MOD + MOD)%のMOD。 以下のために(INT iが= 1 ; I <= N; I ++ ) ANS =(ANS + TOT [N] [i])と%のMOD。 用(int型、L = 1、L <= M、L ++ ){ memsetの(wron、0、はsizeof (wron))。 wron [ 0 ] [N] = 1 。 以下のための(int型私は= 1 ; I <= N; I ++ ) のための(INT J = NIあり、j <= N + I; J ++ ) wron [I] [J] =((wron [I- 1 ] [J] + wron [ I- 1 ] [J- 1 ] * [I] [L]%MOD + wron [I- 1 ] [J + 1 ] *(和[I] -a [I] [L])%MOD)%のMOD + MOD)%のMOD。 用(INT J = N + 1、J <= N * 2 ; J ++ ) ANS =((ANS-wron [n]は[J])%MOD + MOD)%のMOD。 } のprintf(" %のLLD \ n " 、ANS)。 リターン 0; }