Computer >> คอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C++

พาร์ติชันผลรวมเฉลี่ยสูงสุดของอาร์เรย์ใน C++


คำชี้แจงปัญหา

จากอาร์เรย์ เราแบ่งแถวของตัวเลข 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