[#1782] feat(MaxAverageRatio): Add priority queue method
This commit is contained in:
@@ -6,7 +6,45 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
public class Solution {
|
public class Solution
|
||||||
|
{
|
||||||
|
public double MaxAverageRatio(int[][] classes, int extraStudents)
|
||||||
|
{
|
||||||
|
// use priority queue
|
||||||
|
var pq = new PriorityQueue<ClassInfo, double>();
|
||||||
|
|
||||||
|
// 初始化:將所有班級加入優先佇列
|
||||||
|
for (int i = 0; i < classes.Length; i++)
|
||||||
|
{
|
||||||
|
int pass = classes[i][0];
|
||||||
|
int total = classes[i][1];
|
||||||
|
|
||||||
|
double gain = CalculateGain(pass, total);
|
||||||
|
|
||||||
|
pq.Enqueue(new ClassInfo(pass, total), -gain);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < extraStudents; i++)
|
||||||
|
{
|
||||||
|
var classInfo = pq.Dequeue();
|
||||||
|
|
||||||
|
classInfo.Pass++;
|
||||||
|
classInfo.Total++;
|
||||||
|
|
||||||
|
double newGain = CalculateGain(classInfo.Pass, classInfo.Total);
|
||||||
|
pq.Enqueue(classInfo, -newGain);
|
||||||
|
}
|
||||||
|
|
||||||
|
double totalRatio = 0;
|
||||||
|
while (pq.Count > 0)
|
||||||
|
{
|
||||||
|
var classInfo = pq.Dequeue();
|
||||||
|
totalRatio += (double)classInfo.Pass / classInfo.Total;
|
||||||
|
}
|
||||||
|
|
||||||
|
return totalRatio / classes.Length;
|
||||||
|
}
|
||||||
|
|
||||||
public double MaxAverageRatioByBruteForce(int[][] classes, int extraStudents)
|
public double MaxAverageRatioByBruteForce(int[][] classes, int extraStudents)
|
||||||
{
|
{
|
||||||
var n = classes.Length;
|
var n = classes.Length;
|
||||||
@@ -54,7 +92,14 @@ public class Solution {
|
|||||||
return CalculateAvergaeRatio(pass, total);
|
return CalculateAvergaeRatio(pass, total);
|
||||||
}
|
}
|
||||||
|
|
||||||
private double CalculateAvergaeRatio(int[] pass, int[] total) {
|
private double CalculateGain(int pass, int total)
|
||||||
|
{
|
||||||
|
// 計算提升率
|
||||||
|
return (double)(pass + 1) / (total + 1) - (double)pass / total;
|
||||||
|
}
|
||||||
|
|
||||||
|
private double CalculateAvergaeRatio(int[] pass, int[] total)
|
||||||
|
{
|
||||||
double sum = 0;
|
double sum = 0;
|
||||||
for (var i = 0; i < pass.Length; i++)
|
for (var i = 0; i < pass.Length; i++)
|
||||||
{
|
{
|
||||||
@@ -64,6 +109,18 @@ public class Solution {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class ClassInfo
|
||||||
|
{
|
||||||
|
public int Pass { get; set; }
|
||||||
|
public int Total { get; set; }
|
||||||
|
|
||||||
|
public ClassInfo(int pass, int total)
|
||||||
|
{
|
||||||
|
Pass = pass;
|
||||||
|
Total = total;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 測試程式
|
// 測試程式
|
||||||
public class Program
|
public class Program
|
||||||
{
|
{
|
||||||
@@ -98,7 +155,7 @@ public class Program
|
|||||||
// Actual:
|
// Actual:
|
||||||
Console.WriteLine("Actual: ");
|
Console.WriteLine("Actual: ");
|
||||||
Console.WriteLine($"Brute Force: {solution.MaxAverageRatioByBruteForce(classes, extraStudents):F6}");
|
Console.WriteLine($"Brute Force: {solution.MaxAverageRatioByBruteForce(classes, extraStudents):F6}");
|
||||||
//Console.WriteLine($"output: {solution.MaxAverageRatio(classes, extraStudents):F6}");
|
Console.WriteLine($"Priority Queue: {solution.MaxAverageRatio(classes, extraStudents):F6}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -125,6 +182,6 @@ public class Program
|
|||||||
// Actual:
|
// Actual:
|
||||||
Console.WriteLine("Actual: ");
|
Console.WriteLine("Actual: ");
|
||||||
Console.WriteLine($"Brute Force: {solution.MaxAverageRatioByBruteForce(classes, extraStudents):F6}");
|
Console.WriteLine($"Brute Force: {solution.MaxAverageRatioByBruteForce(classes, extraStudents):F6}");
|
||||||
//Console.WriteLine($"output: {solution.MaxAverageRatio(classes, extraStudents):F6}");
|
Console.WriteLine($"Priority Queue: {solution.MaxAverageRatio(classes, extraStudents):F6}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user