アドレス:http : //acm.hdu.edu.cn/showproblem.php?pid=1176
中国語のタイトルの意味はあまり説明されていません。
2次元のdp配列を作成します。dp[i] [j]は、i番目の秒にjに該当するパイを意味します。DPを逆にする必要があります。なぜ、0秒から始めて、x = 5の場合、配列を下に移動しても、終点がどこにあるのかわかりません。このルートに沿った最大値は、次の秒ではない可能性があります最大値。しかし、開始点はわかっているので、終了点から開始してdp [0] [5]に移動します。この一般的なルートには多くの未知の状況がありますが、私たちが判断できることの1つ:
私、j
i + 1、j-1 i + 1、j i + 1、j + 1
dp [i] [j]の場合、次のステップに進むには、次のステップの大きい方の値を追加する必要がありますが、これは変更されません。したがって、最後の時点max-1(実際にはmaxからも渡すことができます)から、上に移動します。毎回、i、jの次の行の3つの数値の最大値を取ってから、i、jを追加します。方程式を取得します。
dp【i】【j】+ = max(dp【i + 1】【j-1】、dp【i + 1】【j】、dp【i + 1】【j + 1】);
最後に、開始点としてdp [0] [5]を出力します。
#include <iostream> #include <cstring> #include <algorithm> #include <cstdio> using namespace std; const int maxn = 1e5 + 10 ; int dp [maxn] [ 12 ]; int main() { int n; while(scanf(" %d "、&n)) { if(n == 0 ) break ; memset(dp、0、sizeof (dp)); int t、x; int maxx = -1 ; for(int i = 1 ; i <= n; i ++ ) { scanf(" %d%d "、&x、&t); dp [t] [x] ++ ; if(t> maxx) maxx = t; } for(int i = maxx- 1 ; i> = 0 ; i -- ) { for(int j = 0 ; j <= 10 ; j ++ ) { int mid = max(dp [i + 1 ] [j- 1 ]、dp [i + 1 ] [j]); dp [i] [j] + = max(mid、dp [i + 1 ] [j + 1 ]); } } printf(" %d \ n "、dp [ 0 ] [ 5 ]); } }