2Dマトリックスの高度な問題:2人の最大総カロリー消費量を解きます
問題:
2次元配列calorie [N] [M]が座標(N、M)にアクセスするときに消費されるカロリー値を表す場合、既存の2D行列N xMがあります。今、2人がいます。1人(男の子)は(1、1)で始まり、もう1人(女の子)は(N、1)で始まり、終わり1(N、M)と終わり2(1、M)に到達する必要があります。 )それぞれ。男の子は1ステップで右または下にのみ移動でき、女の子は1ステップで右または上にのみ移動できます。そして、2つのパスでは、1つのミーティングポイントのみが許可され、合計カロリー消費量のうち、このミーティングポイントのカロリーは男の子または女の子の消費量に追加されず、合計カロリー消費量が計算されます。
問題分析:
一見すると、この質問は前の3つの質問よりもはるかに複雑です。しかし、さまざまな条件は別として、それは本質的に最も費用効果の高い解決策の問題です。次に、この記事の主要な制約の分析に焦点を当てます。2つのパス上で許可される交点は1つだけです。
待ち合わせ場所が(i、j)であると仮定します
まず、少年がこの待ち合わせ場所を通過する前後の可能な経路は次のとおりです。
- (i-1、j)->(i、j)->(i + 1、j)
- (i-1、j)->(i、j)->(i、j + 1)
- (i、j-1)->(i、j)->(i、j + 1)
- (i、j-1)->(i、j)->(i + 1、j)
同様に、女の子がこの待ち合わせ場所を通過する前後の可能なパスは次のとおりです。
- (i + 1、j)->(i、j)->(i-1、j)
- (i + 1、j)->(i、j)->(i、j + 1)
- (i、j-1)->(i、j)->(i-1、j)
- (i、j-1)->(i、j)->(i、j + 1)
待ち合わせポイント(i、j)を除いて、他の同じ移動座標はあり得ないため、待ち合わせポイントを通過する2つの前後の可能なパスは次のようになります。
- 男孩:(i-1、j)->(i、j)->(i + 1、j)、女孩:(i、j-1)->(i、j)->(i 、j + 1)
- 男孩:(i、j-1)->(i、j)->(i、j + 1)、女孩:(i + 1、j)->(i、j)->(i -1、j)
で、このブログの記事、座標特定に到達するためのコストの最高の価値のためのアルゴリズムが解消される。このアルゴリズムは、条件の下で最高の価値を見つけるために使用することはできますか?答えはいいえだ。このアルゴリズムによって得られる最大値の配列は、開始点(0、0)からターゲット座標(N、M)までの最小コストであるためです。パスを通過する必要があるのは、ミーティングのポイント(i、j)に限定されません。したがって、現在の問題をより小さな問題に分割する必要があります
2つのパスは、次の4つの部分に分かれています。
- 男の子は出発点から待ち合わせ場所の前に到着します
- 少年は待ち合わせ場所を出て終わりに達した
- 出発点から待ち合わせ場所の前までの女の子
- 女の子は待ち合わせ場所を出て終わりに達した
ただ頼む
- (1、1)から(i-1、j)、(i + 1、j)から(N、M)までの男の子のコストは、(N、1)から(i、j-までの女の子にとって最良の値です。 1)、(i、j + 1)から(1、M)までのコストの最大値の合計
- (1、1)から(i、j-1)、(i、j + 1)から(N、M)までの男の子、および(N、1)から(i + 1、j)までの女の子のコスト(i-1、j)から(1、M)までのコストの最大値の合計
次に、2つを比較し、最良の値を使用して答えを取得します。
つまり、男の子と女の子の始点から集合点までの最も価値のある一連のパスコストと、集合点から終点までの最も価値のある一連のパスコスト、合計4つを要求する必要があります。コスト配列。
いくつかの小さな詳細があります:
- i-1、i + 1、j-1、j + 1は座標間隔内にある必要があるため、交点(i、j)2 <= i <= N-1、2 <= jを取得できます。 <= M- 1
アルゴリズムは次のとおりです。
/**
*
* @param {int[N][M]} calorie
* @param {int} N
* @param {int} M
*/
var calories = function(calorie, N, M) {
var totalCalories = 0
var BoyStartToMeet = construct(N, M)
var BoyEndToMeet = construct(N,M)
var GirlStartToMeet = construct(N, M)
var GirlEndToMeet = construct(N, M)
for (let i = 1; i <= N; i++) {
for (let j = 1; j <= M; j++) {
BoyStartToMeet[i][j] = Math.max(BoyStartToMeet[i - 1][j], BoyStartToMeet[i][j - 1]) + calorie[i][j]
}
}
for (let i = N; i >= 1; i--) {
for (let j = M; j >= 1; j--) {
BoyEndToMeet[i][j] = Math.max(BoyEndToMeet[i + 1][j], BoyStartToMeet[i][j + 1]) + calorie[i][j]
}
}
for (let i = N; i <= 1; i++) {
for (let j = 1; j <= M; j++) {
GirlStartToMeet[i][j] = Math.max(BoyStartToMeet[i + 1][j], BoyStartToMeet[i][j - 1]) + calorie[i][j]
}
}
for (let i = 1; i <= N; i++) {
for (let j = M; j >= 1; j--) {
GirlEndToMeet[i][j] = Math.max(BoyEndToMeet[i - 1][j], BoyStartToMeet[i][j + 1]) + calorie[i][j]
}
}
for (let i = 2; i < N; i++) {
for (let j = 2; j < M; j++) {
var opt1 = BoyStartToMeet[i][j - 1] + BoyEndToMeet[i][j + 1] + GirlStartToMeet[i + 1][j] + GirlEndToMeet[i - 1][j]
var opt2 = BoyStartToMeet[i - 1][j] + BoyEndToMeet[i + 1][j] + GirlStartToMeet[i][j - 1] + GirlEndToMeet[i][j + 1]
totalCalories = Math.max(totalCalories,Math.max(opt1,opt2))
}
}
return totalCalories
}
var construct = function(N, M) {
var c = new Array()
for (let i = 0; i < N; i++) {
c[i] = new Array()
for (let j = 0; j < M; j++) {
c[i][j] = 0
}
}
return c
}
ソリューションのコードについて質問やパズルがある場合は、コメントしてください。できる限りお答えします。