トピックの要件
長さnのロープを渡してください。ロープをmの長さの整数の長さにカットしてください(mおよびnは整数、n> 1およびm> 1)。各ロープの長さはk [0]、k [1]、...、k [m]。k [0] xk [1] x ... xk [m]の可能な最大積は何ですか?たとえば、ロープの長さが8の場合、ロープをそれぞれ長さ2、3、3の3つのセクションにカットします。このとき得られる最大の積は18です。
1.動的プログラミング分析とソリューション
まず、動的プログラミングを見てみましょう。動的プログラミングを使用して解決される一般的な問題は何ですか?
問題が問題の最適な解決策を求めており、問題がいくつかのサブ問題に分解される可能性があり、オーバーラップする小さなサブ問題がある場合。
特徴:
- 問題全体の最適解は、各問題に依存する最適解です
- 大きな問題をいくつかの小さな問題に分解し、互いに重なり合う小さな副問題があります
- 問題を上から下に分析し、問題を下から上に解決します
次に、動的プログラミングのアイデアを使用して、ロープを切断する方法について考えてみましょう。
したがって、f(1)= 1、f(2)= 1、f(3)= 2であることがわかります。
サブ問題の最適解をアレイ製品に保存します。配列のi番目の要素は、長さiのロープをいくつかのセグメント(f(i))に切断した後の各セグメントの長さ積の最大値を表します。
コードの実装は次のとおりです。
int maxproductAfterCutting(int length)
{
if (length < 2)
return 0;
if (length == 2)
return 1;
if (length == 3)
return 2;
int* products = new int[length + 1];
products[0] = 0;
products[1] = 1;
products[2] = 2;
products[3] = 3;
int max = 0;
for (int i = 4; i <= length; i++)
{
max = 0;
for (int j = 1; j < i / 2; j++)
{
int product = products[i] * products[i - j];
if (max < product)
max = product;
products[i] = max;
}
}
max = products[length];
delete[] products;
return max;
}
2.貪欲なアルゴリズム
貪欲なアルゴリズムの基本的な考え方は次のとおりです。貪欲アルゴリズムを使用して問題を解決する場合、すべてのステップで貪欲な選択を行うことができ、この選択に基づいて、最適なソリューションを取得できると判断します。
n> = 5の場合、可能な限り長さ3のロープを切断します。残りのロープ長が4の場合、ロープを2つの長さのロープに切断します。
int maxproductAfterCutting1(int length)
{
if (length < 2)
return 0;
if (length == 2)
return 1;
if (length == 3)
return 2;
//尽可能多的剪去长度为3的绳子段
int timeOf3 = length / 3;
//当绳子最后剩下的长度为4的时候,不能再剪去长度为3的绳子段
//此时更好的方法就是把绳子剪成长度为2的两段
if (length - timeOf3 * 3 == 1)
timeOf3 -= 1;
int timeOf2 = (length - timeOf3 * 3) / 2;
return (int)(pow(3, timeOf3)) * (int)(pow(2, timeOf2));
}
では、なぜこのような考え方を選ぶのでしょうか。
n> = 5の場合、2(n-2)> nおよび3(n-3)> nであることを証明できます。つまり、残りのロープの長さが5以上の場合、彼をカットしますロープの3または2本の長さに。
n> 5、3(n-3)> = 2(n-2)の場合、できるだけ長いロープをカットする必要があります。