Leetcode 887.エッグドロップ【ダイナミックプランニング】

問題の説明

あなたは取得しますK卵を、1から使用可能1N合計N階建ての建物。

それぞれの卵の機能は同じですが、卵が割れると落とせません。

あなたは床が知っているF満たすために0 <= F <= Nすべての卵からF上の階から分解されF、その床や床の卵が壊れていないだろうよりも低く落ちるが。

それぞれの動きは、あなたが(あなたが完全に卵を持っている場合)、卵を取り、あらゆる床からそれを取ることができますX(満たすために低下しました1 <= X <= N)。

あなたの目標は、正確に把握することでF価値があります。

関係なくFどのように初期値の、あなたが決めるF動き値の最小数はどのくらいですか?

問題解決レポート

d p [ ] [ j ] dp [i] [j] i、卵とj床に必要な最小オペランドあることを意味します。
伝達方程式は次のとおりです。
d p [ i ] [ j ] = m i n ( d p [ i ] [ j ] , m a x ( d p [ i 1 ] [ k 1 ] , d p [ i ] [ j k ] ) + 1 )        ( 1 k j ) dp [i] [j] = min(dp [i] [j]、max(dp [i-1] [k-1]、dp [i] [jk])+ 1)\; \; \;( 1 \ le k \ le j)

気づいた d p [ i 1 ] [ k 1 ] , d p [ i ] [ j k ] dp [i-1] [k-1]、dp [i] [jk] k k のサイズは、
次のように反対方向に変化します。 d p [ i ] [ j ] dp [i] [j] をできるだけ小さくし、 d p [ i 1 ] [ k 1 ] , d p [ i ] [ j k ] dp [i-1] [k-1]、dp [i] [jk] 可能な限り等しい
ので、二分法を使用してこれを適切に見つけることができます k k 値。

以下の最適化手法の多くは継続されます。

実装コード

class Solution {
public:
    int superEggDrop(int K, int N) {
		vector<vector<int>> dp(K + 1, vector<int>(N + 1));
		for (int j = 1; j <= N; ++j) dp[1][j] = j;
		for (int i = 2; i <= K; ++i) {
			for (int j = 1; j <= N; ++j) {
				dp[i][j] = j;
				int left = 1, right = j;
				while (left < right) {
					int mid = left + (right - left) / 2;
					if (dp[i - 1][mid - 1] < dp[i][j - mid]) left = mid + 1;
					else right = mid;
				}
				dp[i][j] = min(dp[i][j], max(dp[i - 1][right - 1], dp[i][j - right]) + 1);
			}
		}
		return dp[K][N];
    }
};

参考文献

[1] Leetcode 887.エッグドロップ
[2] [LeetCode] 887.スーパーエッグドロップ

MD_
139の元の記事を公開 賞賛8 10,000+ビュー

おすすめ

転載: blog.csdn.net/qq_27690765/article/details/105452129