标签:
5 2
1 2 3 4 5
120
由于括号可以随意添加,那么最直接的想法是把一段式子分成左右两段,由这两段递推得解。由于不等式的性质,左右当左右两段取到最大值时合起来一定最优(a>c>0, b>d>0⇒a+b>c+d, a*b>c*d)。
设F(l, r, k)为[l, r]上数字添加k个乘号算得的最大值,则方程:
F(l, r, k) = A[l], l=r;
F(l, r, k) = max{ max{F(l, d, k’) + F(d+1, k-k’)} (l≤d<r, 0≤k’≤k, k’≤d-l, k-k’≤r-d-1), max{F(l, d, k’) + F(d+1, k-k’-1)} (l≤d<r, 0≤k’≤k, k’≤d-l, k-k’≤r-d) }
当然,这样的话枚举乘号个数的时候会比较复杂,可以简化。
设F(i, j)为前i个数添加j个乘号的最大值,则方程:
F(i, j) = max{F(k, j) + (S[i] - S[k] + A[k]), F(k, j-1) * (S[i] - S[k] + A[k])} (0<k<i)
1 #include <iostream> 2 using namespace std; 3 unsigned long long F[102][102]; 4 unsigned long long S[102]; 5 unsigned long long A[102]; 6 unsigned long long ans; 7 int N, K; 8 int main() 9 { 10 cin >> N >> K; 11 for (int i = 1; i <= N; ++i) 12 cin >> A[i]; 13 S[N] = A[N]; 14 for (int i = N - 1; i >= 1; --i) 15 S[i] = S[i + 1] + A[i]; 16 F[1][0] = A[1]; 17 for (int i = 2; i <= N; ++i) { 18 for (int j = 0; j != i && j <= K; ++j) { 19 for (int k = 1; k != i; ++k) { 20 F[i][j] = max(F[k][j] + (S[k + 1] - S[i] + A[i]), F[i][j]); 21 if (F[i][j] > ans) 22 ans = F[i][j]; 23 } 24 } 25 for (int j = 1; j != i && j <= K; ++j) { 26 for (int k = 1; k != i; ++k) { 27 F[i][j] = max(F[k][j - 1] * (S[k + 1] - S[i] + A[i]), F[i][j]); 28 if (F[i][j] > ans) 29 ans = F[i][j]; 30 } 31 } 32 } 33 cout << F[N][K]; 34 return 0; 35 }
标签:
原文地址:http://www.cnblogs.com/smileandyxu/p/5367706.html