主題の背景は本当にその年のことを思い出します。。。
言ってはいけない、この質問、一見または暴力的な取得する30分良いに乗るが、なぜなら私は試験の詳細に対処していなかった考え方の問題のゼロバースト。
暴力の30分の一般的な考えの複雑さは$ O(NMD)$でなければなりませんが、データの範囲は、本当に恐ろしいdは単純にACことはできません。
30件のアイデアは、最適化のスペースが素晴らしいではありません(しかし、神ベンは、TQLを伝達行列を加速するために、迅速なパワーを思い付いた)ように見えます。
私たちは彼女にn日でビスケットを与えるためにn個のビスケットの最大なので、アップ日の実数を観察しているため、私たち、その後、最初にすべての確かに複雑に入れることができないdは、私の考えを変更するだけでなく、それはそれをシフトする方法を検討しますこの設計の状況に応じて:集合$ F [i]の[j]は$が実際に彼女の日$ I $の合計数を表し、$ J $はビスケットを与えます。その後、我々は[I] [J] = \ Sigma_ {K = JM} ^ J-1 {F [I-1] [K]} $ F $状態方程式に移行することができ、
$ {[I] [N] * C_D ^ I F} $回答= \シグマ。それとも嘘が、私たちの現在のDP式はまだOの$(N ^ 3)$での複雑さをよく理解は、式の後ろに最適化を検討し、接頭辞を考えるのは簡単ですので、範囲及び形態であり、最適化。複雑さは$ O(N ^ 2)$になります。
注意すべきこの質問のポイントがあります:まず、dが、それは方程式を解くについて行わいくつかのポイントを組み合わせることが最善である、我々は通常、使用方法を見つけるには大きすぎます。
第二層のループが続く、それは私が* $(M-1)$からJ $ $ $ $私が列挙されている必要がありますが、接頭辞およびN- $ $を処理する、とあなたは接頭辞になっているので、次の層のサービスが、次のレベル$ N $を使用する可能性があるので、接頭辞と$ N $に取り組まなければなりません。
まだやることがたくさんDPのタイトルを最適化する前に、この問題を考えることができ、それの思想。
1の#include <iostreamの> 2の#include <cstdioを> 3の#include <CStringの> 4の#include <cmath> 5の#include <キュー> 6の#include <ベクトル> 7 の#define INT長い長 8 の#defineっ長い長い 9 使用 名前空間はstd; 10 のconst int型 N = 2005 。 11 のconst int型 MOD = 998244353 。 12 int型DP [N] [N]、合計[N] [N]、INV [N]。 13 INT qpow(INT A、INTB){ 14 INT ANS = 1 。 15 %= MOD。 16 一方、(B){ 17 であれば(B&1)ANS = ANS *%のMOD。 18 B >> = 1 。 19 = *%のMOD。 20 } 21の リターンANS。 22 } 23 / * インラインINT C(INT A、INT B){ 24 INT JS = 1LL、facd = 1LL。 25 のjs =(JS * I)%MOD;(; iが= Bを<I ++はi = 1 int型登録)するため 26 以下のために(iは-B + 1 = intを登録; I <= A; iは++){facd = iは%MOD * facd%のMOD; COUT << "L" << facd << ENDL;} 27 リターンfacd * qpowを( JS、MOD-2)%MOD。 28 } * / 29 / * インラインINT C(int型のx、int型のY){ 30 のint facd = 1LL、FACI = 1LL。 31 X%= MOD。 32 のために(; iは= xを<; I = intをレジスタ2 ++ I)FACI =(FACI * I)%MOD。 33 のために(登録INT I = Y-X + 1; iは= yと<; ++ I)facd = I%MOD * facd%のMOD。 34 INT INV = qpow(FACI、MOD-2)。 35 //のprintf( "%LLD%LLD%LLD \ n"は、FACI、facd、INV)。 36 リターンfacd *のINV%のモッズ。 37 } * / 38 INT C(INTY、INT X){ 39 であれば(Y <0LL || X <0LL || Y <X)戻り 0 ; 40 のY%= MOD。 41 であれば(Y == 0LL || X == 0LL)リターン 1 。 42 LL ANS = 1 。 43 のために(INT I = 0LL; iは、X <; iは++ ) 44件 のANS =のANSを*(YI)%MOD。 45 のために(INT I = 1LL; iは= xを<; iは++ ) 46 のANS =のANS * INV [I]%MOD。 47の リターンANS; 48 } 49 メイン(){署名された 50 のint nは、M、Dと、 51 のために(INT I = 1LL; iは++; iは= 2000ll < ) 52の INV [I] = qpow(I、mod- 2LL)。 53 一方(〜のscanf(" %LLD%LLD%LLD "、&N、&D&M)){ 54 であれば(N && M && D!!)ブレーク。 55 であれば(N> D *(M- 1)){プット(" 0 ")。引き続き;} 56 のmemset(DP、0、はsizeof (DP))。 57 のmemset(和、0、はsizeof (合計))。 58 のために(int型 i = 1 ; iがmは<; Iは++ ){ 59 DPは[ 1 ] [I] = 1 。 60 和[ 1 ] [I] = DP [ 1 ] [I] +和[ 1 ] [I- 1 ]。 61 } 62 のために(INT I = M; iは= <N; iは++)和[ 1 ] [i]は=和[ 1 ] [I- 1 ]。 63 INT ANS = 0 。 64の ANS + =(DP [ 1 ] [N] * C(D、1LL))%モッズ; 65 のために(int型 I = 2 iが++; iが=分(D、N)< {) 66の ための(int型 ; J <= N; J ++ J = I ){ 67 DPは、[I] [J] =((和[ I- 1 ] [J- 1 ] -sum [I- 1 ] [MAX(JM、0LL)])%MOD + MOD)%MOD。 68 和[I] [J] =(SUM [I]、[J- 1 ] + DP [I] [J])%MOD。 69 // coutの<< DP [I] [J] <<てendl; 70 } 71件 のANS =(ANS + DP [I] [N] * C(D、I)%のMOD)%MOD。 72 } 73 //COUT << DP [1]〜[N] << ENDL。 74 // (I = 2をint型、iが=分(D、N)<; iが++)のためのANS =(ANS + DP [I] [N] * C(D、I)%のMOD)%MOD。 75 のprintf(" %LLDする\ n "、ANS%のMOD)。 76 } 77 }