このアルゴリズムは、最大の表現を訓練します
制限時間:メモリ制限が1.0S:256.0メガバイト
問題の説明
非常に簡単なタイトル、所与のNデジタルは、最終結果が可能な限り大きいK乗算とNK-1プラス記号の添加、(プラス何括弧)の途中に、それらの相対位置を変更しません。乗算とプラスは、N-1の合計であるため、その正確ごとに隣接する二つの数字の間の符号を持っています。例えば:
N = 5、K = 2,5番号それぞれ1,2,3,4,5、添加することができる:
1 2 *(3 + 4 + 5)= * 24
1 *(2 + 3)* (4 + 5)を45 =
(1 + 2 * 3)*(4 + 5)= 45
......
入力形式
そこ入力ファイル、二つの整数の最初の動作は、スペースで区切られた2つのラインがあり、及びN(2 <= N <= 15、0 <= K <= N-1)Kを表します。スペースで区切られたN個の2行目(0〜9の間の各数値)。
出力フォーマット
出力ファイルのみ1行が最大の必要な結果を表す整数が含まれています
サンプル入力
5 2
1 2 3 4 5
サンプル出力
120
サンプル説明
(1 + 2 + 3)* 4 * 5 = 120
分析:セット開始から最初の数との間のサブアレイが中に挿入され、その乗算の積とすることができる最大数。だから、漸化式があります:
#include <stdio.h>
int main()
{
int N, K;
int a[20] = { 0 };
long long int f[20][20] = { 0 };
int sum[20][20] = { 0 };
scanf("%d %d", &N, &K);
for (int i = 1; i <= N; ++i)
scanf("%d", &a[i]);
for (int i = 1; i <= N; ++i)
{
sum[i][i] = a[i];
for (int j = i+1; j <= N; ++j)
sum[i][j] = sum[i][j-1] + a[j];
}
for (int n = 1; n <= N; ++n)
f[n][0] = sum[1][n];
for (int k = 1; k <= K; ++k)
{
for (int n = k+1; n <= N; ++n)
{
long long int max = f[k][k-1] * sum[k+1][n];
for (int i = k+1; i <= n-1; ++i)
{
if (max < f[i][k-1] * sum[i+1][n])
max = f[i][k-1] * sum[i+1][n];
}
f[n][k] = max;
}
}
printf("%lld", f[N][K]);
return 0;
}