この問題のために、DPは明らかであるが、より素晴らしい状態設計であり、DP [I] [J] [H] [どの]はi番目の行を示し、j番目の列には、差がHであり、0、小Aを表します図1は、UIMを表します。これは宝物に到達する人、そのうちの二人は転送することができるの違いを維持する値を記録する必要はありません。K + 1を超える場合には、フィルムを指示することができるようになります。
初期状態:DP [I] [J] [I]、[J] [0] = 1。列挙I、J、H転送(それが取る小さいので)、Hがkを超えない差であります
伝達方程式:
DP [I] [J] [ H] [0] + = DP [I-1] [j]は[I] [J]ハハ] [1]%MOD; UIMから小さなAを転送することを取ること[I] [J]差hから増加、およびから転送から残されている
DP [I] [J] [ H] [0] + = DP [I]、[J-1] [HA [I] [J] [1]%MOD;
。。DP [I] [J] [H] [1] + = DP [I-1]〜[J] [H + A [I] [J] [0]%MOD ; UIM同様に、彼は差が転送同様に後に低減された
DP [I] [J] [ H] [1] + = DP [I]、[J-1] [H + [I] [J] [0]% MOD。
最後に蓄積されたDP [I] [J] [0] [1]彼らは最終的に、差は0で、最後にFOMAカードを取るために同じ番号から、答えること。
コード:
#include <ビット/ STDC ++ H> 使用して 名前空間STDを、 CONSTの INT N = 950 。 const int型のmod = 1000000007 ; int型ditu [N] [N]。 INT DP [N] [N] [ 18 ] [ 2 ]。 長い 長いANS; INTのN、M、K。 INT メイン(){ scanf関数(" %D%D%D "、&N、&M、およびK); K ++ ; 以下のために(int型 i = 1 ; iが= N <; iは++ ){ ため(INTの J = 1 ; J <= Mであり、j ++ ){ scanf関数(" %のD "、&ditu [I] [J])。 DP [I] [J] [ditu [I] [J] [ 0 ] = 1 ; } } のための(int型 i = 1 ; iが<= N iが++ ){ ため(INT J = 1 ; J <= Mであり、j ++ ){ ため(INT H = 0 ; H <= K; H ++ ){ DP [I ] [J] [H] [ 0 ] + = DP [I- 1 ] [j]は、[(H-ditu [I] [J] + K)%のK] [ 1】%MOD。 DP [I] [J] [H] [ 0 ] + = DP [I]、[J- 1 ] [(H-ditu [I] [J] + K)%のK] [ 1 ]%MOD。 DP [I] [J] [H] [ 1 ] + = DP [I- 1 ] [j]は、[(H +のditu [I] [J] + K)%のK] [ 0 ]%MOD。 DP [I] [J] [H] [ 1 ] + = DP [I]、[J- 1 ] [(H +のditu [I] [J] + K)%のK] [ 0 ]%MOD。 } } } のための(int型 i = 1 ; iが<= N; iが++ ){ ため(INT J = 1 ; J <= M; J ++){ ANS =(ANS + DP [I] [J] [ 0 ] [ 1 ])%のMOD。 } } のprintf(" %LLDを\ n " 、ANS)。 リターン 0 ; }