문제 설명
주어진 배열에서 숫자 A의 행을 최대 K개의 인접한(비어 있지 않은) 그룹으로 분할한 다음 점수는 각 그룹의 평균 합계입니다. 채점할 수 있는 최대 점수는 얼마입니까?
예
입력 배열이 {9, 2, 5, 3, 10}이면 다음과 같이 배열을 분할할 수 있습니다. -
{9} {2, 5, 3} 및 {10}의 평균 합계는 -
9 + (2 + 5 + 3)/ 3 + 10 =22.33
알고리즘
우리는 이 문제를 해결하기 위해 암기 기술을 사용할 수 있습니다 -
- 메모[i][k]를 A[i에서 n-1]까지의 최대 K 부분으로 나눈 최고 점수로 둡니다.
- 첫 번째 그룹에서 A[i ~ n-1]을 A[i ~ j-1] 및 A[j ~ n-1]로 분할하면 후보 분할의 점수 평균(i, j) + 점수(j, k-1)), 여기서 평균(i, j) =(A[i] + A[i+1] + … + A[j-1]) / (j – i). 이 중에서 가장 높은 점수를 받습니다.
- 전체적으로 일반적인 경우의 재귀는 다음과 같습니다. memo[n][k] =max(memo[n][k], score(memo, i, A, k-1) + average(i, j ))
예
이제 예를 살펴보겠습니다 -
#include <bits/stdc++.h>
using namespace std;
define MAX 1000
double memo[MAX][MAX];
double score(int n, vector<int>& arr, int k) {
if (memo[n][k] > 0) {
return memo[n][k];
}
double sum = 0;
for (int i = n - 1; i > 0; i--) {
sum += arr[i];
memo[n][k] = max(memo[n][k], score(i, arr, k - 1) + sum / (n - i));
}
return memo[n][k];
}
double getLargestSum(vector<int>& arr, int K) {
int n = arr.size();
double sum = 0;
memset(memo, 0.0, sizeof(memo));
for (int i = 0; i < n; i++) {
sum += arr[i];
memo[i + 1][1] = sum / (i + 1);
}
return score(n, arr, K);
}
int main() {
vector<int> arr = {9, 2, 5, 3, 10}; int K = 3;
cout << "Largest sum = " << getLargestSum(arr, K) << endl;
return 0;
} 출력
위의 프로그램을 컴파일하고 실행할 때. 다음 출력을 생성합니다 -
Largest sum = 22.3333