動的なプログラミングのアイデア:
N + DP1 1の2つの長さ、DP2のアレイを提供する、DP [i]はi番目の停止位置に特定のエネルギーかどうかを示す、DP [I] = 0が届かない示し、DP [I] = 1が到達することを示し、
初期DP1 [1 ... N] = 1、それが任意の位置から発現させることができます、
各Djのための距離を歩いて、または左方向、すなわち、DP2で示される位置が到達可能である、伝達方程式を右、DJは完了距離を奪うことができます。
IF(DP1 [J] == 1 && J + D [i]は<= N)
DP2 [J + D [I] = 1。
IF(DP1 [J] == 1 && J - D [i]が> = 1)
DP2 [J - D [I] = 1。
DP1 = DP2、ステップ2を繰り返します。
ディのすべてのステップは、DPなければならないため[j]はNの合計は、O(N×M)、O(N)の空間的な複雑さの時間複雑さをM回X、一度トラバース。
#include <iostreamの> する#include <ベクトル> 使用して名前空間STD; ボイドget_res(N-INT、INT mを、ベクトル<INT>&D){ ベクトル<整数> DP1(N + 1、0); ベクター<整数> DP2れます( ; +、N-、0、1) 二つの配列を使用する//レコードの理由は、DP2にDP1から転送され、移動している; // DPのみ計算場合、転送は「カバー」一過可能性があるためである可能性のある遷移点 以下のために(; I <= N-I ++はI = 0 INT) DP1 [I] = 1; のために(; iがm <; I = 0 int型Iが++){ 。(INTのために1 = J; J <= N- ; J ++){ DP2は[J] = 0; //説明DP1 [J] ;! Dを移動する所定の距離の後に[j]を、DP2に転送されない[I] = 0 IF(DP1 [J] == && D + J. 1 [I] <= N-) ; DP2は、[D + J [I] = 1である 。= 1) - 。D [I]はIF(DP1 [J] 1 && J ==> DP2がある[J - D [ I] = 1。 } DP1 = DP2、DP1が更新即ちDP2にDP1にコピーした後に計算//エンド、 } INT ANS = 0; {(。; I <= N-I ++はINT I = 1)のための IF(DP2 [I ] == 1) ++ ANS; } COUT ANS << << ENDL; } int型のmain(){ int型N- = 0、M = 0; CIN >> N-M; ベクター<整数> D(M、0 ); Iがm <;(I = 0をint型のためのI ++)は CIN >> D [I]; get_res(N、M、D); 戻り0; }
参考ブログ:https://blog.csdn.net/likewind1993/article/details/100176127