質問表面:
背景
JerryZhouの学生は、多くの場合、自分自身を作るために練習を適応させます。
その日、彼は質問を適応しました。。。。。
説明
N * Nは、正の整数乗を充填されるいくつかの市松有する
他のボックスは0を配置しながらします。
マップの左上隅から誰かを取得し、あなたは右下の隅に到達するまで、あなたはまた、右に行くことができ、ダウンすることができます。
通じ途中で、彼は正方形の数を奪いました。(0デジタルボックスを除去した後)、
合計3回の右上隅を下げる離れ左上から人、最大数の合計が達成ように、3つのパスを見つけることを試みます。
フォーマット
入力形式
最初のライン:N(4 <= N < = 20)
次に、N * Nの行列、行列の各要素が0以上、さらに80以上であります
出力フォーマット
最大の和を表す線。
聞く...私は古典的なDPのようなものを聞きました...
とにかく、私はしないでください...
プレスを行うには時間がかかり、その後、3回繰り返す:私は非常にひたむきな考え始めました
その後、その後、WAの音に耳を傾けます...
とにかく、最終的OOO私も料理し、問題を解決するには、見て... oooのの考えである考え抜か
より多くの重要な結論があります:
行列では、我々は唯一下ることができるかどうか起源の前提、知っている、右、そして行くステップ数、行、列の数を、2は三分の一を押すことができる場所を知っています。
そして、同じ場所に2点を来る、ステップの数が同じで過ごすことになります。
これらの結論は、私たちのアイデアからサポートしています。同時に3ポイントを手放します。
建設が状態を次の試してください。F [X] [I] [J] [k]は、工程の代表は、xを歩いて、I、J、K 3を代表するものであり、i番目の行、j番目、k番目の行を歩きました。
実際には、i行目に相当するが、X-K + 2列の行X-J + 2列のk行目のx-I + 2行jに来ます。
現在の状態を更新するために、最良の状態のいずれかを選択した8つの状態から、すなわち、状態ごとに、8つの状態前の状態にあり、最大であろう(左からそれぞれ点と上から来ます)。
式は次のように書かれています:
F [X、I、J、K] = MAX(F [X- 1、I- 1、J、K]、F [X- 1、I、J- 1、K]、F [X- 1、I 、J、 - K- 1 ]、前記上部//のいずれ
F [X- 1、I- 1、J- 1、K]、F [X- 1、I- 1、J、 - K- 1 ]、F [X- 1、I、J- 1、 - K- 1 ]、上から2〜//ここで、
F [X- 1、I- 1、J- 1、 - K- 1 ]、//先頭から3つのすべてを
F [X- 1、I、J、K])//ない上から3個
+追加する必要性に対応する//値A / 2/3点追加
(以前の状態対応fが0であるので、それより大きい任意に正当な状態がある場合、特別なコード境界が、である、無効と判断されていません)
グリッドの数がなくなって除去されるために、あなたがアップ追加したくない、任意の2/3のポイントには判断が同じ広場に行ったんですが。(私は愚かな...そこにいる三つの位置が対で互いに素:!あるI = J && J = K = K && I !!、私と私=行にJ && J = K ... !!)
コードは以下の通りであります:
書式#include <cstdioを> する#include <cstdlib> int型N; INT V [ 21 ] [ 21 ]。 INT [F 41 ] [ 21 ] [ 21 ] [ 21 ]。 int型(最大のint、int型 B){ 返す > bは?:B;} ボイドDP(){ ため(int型のx = 1であり、x <= 2 * N- 2 ; X ++ ){ ため(INT iは= 1 ; I <= X + 1&& I <= N; I ++ ){ ため(INT J = 1 ; J <= X + 1 && J <= N; J ++ ){ ための(int型のk = 1 ; K <= X + 1 && K <= Nであり、k ++ ){ int型の追加; もし(I == J && J == k)を追加= V [i]が[X-I + 2 ]。 もし(I == J && J = K!)を追加= V [i]が[X-I + 2 ] + V [k]が[X-K + 2 ]。 もし(I = J && J == K!)を追加= V [i]が[X-I + 2 ] + V [J] [X-J + 2 ]。 もし(I == K && J = K!)を追加= V [i]が[X-I + 2 ] + V [J] [X-J + 2 ]。 もし(I = J && J = K && I = K!!)を追加= V [i]が[X-I + 2 ] + V [J] [X-J + 2 ] + V [k]が[X-K + 2 ]。 F [X] [I] [J] [K] = MAX(F [X- 1 ] [I- 1 ] [j] [k]は、MAX(F [X- 1 ] [I] [J- 1 ] [K]、MAX(F [X- 1 ] [I] [J] [K- 1 ]、 MAX(F [X - 1 ] [I- 1 ] [J- 1 ] [k]は、MAX(F [ X- 1 ] [I- 1 ] [J] [K- 1 ]、MAX(F [X- 1] [I]、[J- 1 ] [K- 1 ] 、MAX(F [X - 1 ] [I- 1 ] [J- 1 ] [K- 1 ]、F [X- 1 ] [I] [J ] [K])))))))+ 加えます。 } } } } } int型のmain(){ scanf関数(" %のD "、&N)。 以下のために(INT iが= 1 ; I <= Nは、I ++ ){ ため(INT J = 1 J ++; J <= N ) (scanf関数を"%のD "& V [I] [J]); } F [ 0 ] [ 1 ] [ 1 ] [ 1 ] = V [ 1 ] [ 1 ]; DP(); のprintf(" %dの」、F [ 2 * N- 2 ] [N] [N] [N]); 戻り 0 ; }