<p>There are <code>n</code> workers. You are given two integer arrays <code>quality</code> and <code>wage</code> where <code>quality[i]</code> is the quality of the <code>i<sup>th</sup></code> worker and <code>wage[i]</code> is the minimum wage expectation for the <code>i<sup>th</sup></code> worker.</p>

<p>We want to hire exactly <code>k</code> workers to form a <strong>paid group</strong>. To hire a group of <code>k</code> workers, we must pay them according to the following rules:</p>

<ol>
	<li>Every worker in the paid group must be paid at least their minimum wage expectation.</li>
	<li>In the group, each worker&#39;s pay must be directly proportional to their quality. This means if a worker&rsquo;s quality is double that of another worker in the group, then they must be paid twice as much as the other worker.</li>
</ol>

<p>Given the integer <code>k</code>, return <em>the least amount of money needed to form a paid group satisfying the above conditions</em>. Answers within <code>10<sup>-5</sup></code> of the actual answer will be accepted.</p>

<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>

<pre>
<strong>Input:</strong> quality = [10,20,5], wage = [70,50,30], k = 2
<strong>Output:</strong> 105.00000
<strong>Explanation:</strong> We pay 70 to 0<sup>th</sup> worker and 35 to 2<sup>nd</sup> worker.
</pre>

<p><strong class="example">Example 2:</strong></p>

<pre>
<strong>Input:</strong> quality = [3,1,10,10,1], wage = [4,8,2,2,7], k = 3
<strong>Output:</strong> 30.66667
<strong>Explanation:</strong> We pay 4 to 0<sup>th</sup> worker, 13.33333 to 2<sup>nd</sup> and 3<sup>rd</sup> workers separately.
</pre>

<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>

<ul>
	<li><code>n == quality.length == wage.length</code></li>
	<li><code>1 &lt;= k &lt;= n &lt;= 10<sup>4</sup></code></li>
	<li><code>1 &lt;= quality[i], wage[i] &lt;= 10<sup>4</sup></code></li>
</ul>

//T.C = O(N*LogN), S.C = O(K+N)

class Solution {
public:
    double mincostToHireWorkers(vector<int>& quality, vector<int>& wage, int k) {
        double ans = DBL_MAX;
        int n = quality.size();

        // (wage_of_manager/quality_of_manager) must be equals to (wage_of_worker/quality_of_worker) for every worker selected
        // here, wage_of_worker is variable, so, we need to evaluate wage_of_worker to make them equal
        // wage_of_worker = (wage_of_manager/quality_of_manager) * quality_of_worker;
        // if the ratio_of_manager is lesser than the worker then that worker can't be selected

        // NOTE: the worker can be selected as a manager iff it has at least k workers having ratio lesser than him


        //ratio is fixed and quality is selected'
        //Create a wage/qualtiy ratio array
        vector<pair<double, int>>wage_to_qualty_ratio(n, {0,0});
        for(int i=0; i<n; i++){
            double ratio = (double) wage[i]/quality[i];
            wage_to_qualty_ratio[i] = {ratio, quality[i]};
        }

        //wage_to_qualty_ratio array will be used to choose the manager
        //manager which has the least wage/quality ratio will be preffered, becz uska wage quality k according best h
        sort(wage_to_qualty_ratio.begin(), wage_to_qualty_ratio.end());

        //maxheap is created to store quality of k workers
        //quality hume minimum chaiye taki wages kam aye 
        //wage_of_worker = (wage_of_manager/quality_of_manager) * quality_of_worker
        priority_queue<double>maxheap;

        //ab hum ek-ek karke manager select karenge and maxheap store karega previous k smallest quality workers
        double sum_of_qualities = 0;
        for(int manager=0; manager<k; manager++){
            maxheap.push(wage_to_qualty_ratio[manager].second);
            sum_of_qualities += wage_to_qualty_ratio[manager].second;
        }
        
        //kth worker is selected as manager becz, hume k workers select krne h, aage wale can't be chosen becz unka ratio > manager (k-1th worker)
        ans = (double) wage_to_qualty_ratio[k-1].first * sum_of_qualities;

        //Check for rest of the managers
        for(int manager=k; manager<n; manager++){
            maxheap.push(wage_to_qualty_ratio[manager].second);
            sum_of_qualities += wage_to_qualty_ratio[manager].second;
            sum_of_qualities -= maxheap.top();
            maxheap.pop();
            double temp = (double) wage_to_qualty_ratio[manager].first * sum_of_qualities;
            ans = min(ans, temp);
        }

        return ans;

    }
};
27600