マイDPのトレーニングプログラム:3は、パネルの数を取ります

質問表面:

背景

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型(最大のintint型 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 ; 
}

おすすめ

転載: www.cnblogs.com/Zarax/p/12041655.html