これは反復動的計画法のソリューションです。
再帰的なバージョン(同じような実行時間を持つ必要があります) とは対照的です。
基本的な考え方:
A[position][count]
は、乗算position
を使用して、位置 で終わる最大の数です。count
そう:
A[position][count] = max(for i = 0 to position
A[i][count-1] * input.substring(i, position))
各位置と各カウントに対してこれを行い、必要な乗算回数でこれらのそれぞれを残りの文字列全体で乗算します。
複雑:
挿入する乗算演算子を含む文字列|s|
を指定すると...m
O(m|s|2g(s))
乗算の複雑さはg(s)
どこにありますか。
Java コード:
static long solve(String digits, int multiplications)
{
if (multiplications == 0)
return Long.parseLong(digits);
// Preprocessing - set up substring values
long[][] substrings = new long[digits.length()][digits.length()+1];
for (int i = 0; i < digits.length(); i++)
for (int j = i+1; j <= digits.length(); j++)
substrings[i][j] = Long.parseLong(digits.substring(i, j));
// Calculate multiplications from the left
long[][] A = new long[digits.length()][multiplications+1];
A[0][0] = 1;
for (int i = 1; i < A.length; i++)
{
A[i][0] = substrings[0][i];
for (int j = 1; j < A[0].length; j++)
{
long max = -1;
for (int i2 = 0; i2 < i; i2++)
{
long l = substrings[i2][i];
long prod = l * A[i2][j-1];
max = Math.max(max, prod);
}
A[i][j] = max;
}
}
// Multiply left with right and find maximum
long max = -1;
for (int i = 1; i < A.length; i++)
{
max = Math.max(max, substrings[i][A.length] * A[i][multiplications]);
}
return max;
}
非常に基本的なテスト:
System.out.println(solve("99287", 1));
System.out.println(solve("99287", 2));
System.out.println(solve("312", 1));
版画:
86304
72036
62
はい、最大値を出力するだけです。必要に応じて、実際に合計を出力することはそれほど難しくありません。