Skip to content
thecscience
THECSICENCE

Learn everything about computer science

  • Home
  • Human values
  • NCERT Solutions
  • HackerRank solutions
    • HackerRank Algorithms problems solutions
    • HackerRank C solutions
    • HackerRank C++ solutions
    • HackerRank Java problems solutions
    • HackerRank Python problems solutions
thecscience
THECSICENCE

Learn everything about computer science

HackerRank Mining Problem Solution

Yashwant Parihar, August 7, 2023August 1, 2024

In this post, we will solve HackerRank Mining Problem Solution.

There are n gold mines along a river, and each mine i produces w, tons of gold. In order to collect the mined gold, we want to redistribute and consolidate it amongst exactly k mines where it can be picked up by trucks. We do this according to the following rules:
You can move gold between any pair of mines (i.e.. i and j, where 1 <i<j<n).

All the gold at some pickup mine i must either stay at mine i or be completely moved to some other mine, j.
Move w tons of gold between the mine at location, and the mine at location, at a cost of xxxw.
Given n. k, and the amount of gold produced at each mine, find and print the minimum cost of consolidating the gold into k pickup locations according to the above conditions.
Input Format
The first line contains two space-separated integers describing the respective values of n (the number of mines) and k (the number of pickup locations).
Each line of the n subsequent lines contains two space-separated integers describing the respective values of x, (the mine’s distance from the mouth of the river) and w, (the amount of gold produced in tons) for mine i.
Note: It is guaranteed that the mines are will be given in order of ascending location.

Output Format

Print a single line with the minimum cost of consolidating the mined gold amongst K different pickup sites according to the rules stated above.

Sample Input 0

3 1
20 1
30 1
40 1

Sample Output 0

20

Explanation 0
We need to consolidate the gold from n = 3 mines into a single pickup location (because k = 1). The mines are all equidistant and they all produce the same amount of gold, so we just move the gold from the mines at locations X = 20 and x = 40 to the mine at x = 30 for a minimal cost of 20.

Sample Input 1

3 1
11 3
12 2
13 1

Sample Input 1

4

Explanation 1
We need to consolidate the gold from n = 3 mines into a single pickup location (because k = 1). We can achieve a minimum cost of 4 by moving the gold from mines = 12 and x = 13 to the mine at x = 11.

HackerRank Mining Problem Solution
HackerRank Mining Problem Solution

Mining C Solution

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>

int x[5000];
int w[5000];

int64_t val[5000][5000];
int64_t a[5000], b[5000];

int64_t mining()
{
    int n, k, i;
    scanf("%d %d", &n, &k);
    for(i = 0; i < n; ++ i)
        scanf("%d %d", &x[i], &w[i]);

    for(i = 0; i < n; ++i)
    {
        int64_t left = 0, right = 0, acc = 0;
        int s, j;

        for(j = i + 1, s = i; j < n; ++ j)
        {
            acc += w[j] * (int64_t)(x[j] - x[s]);
            right += w[j];

            while(s < j && left + w[s] < right)
            {
                acc += (left + w[s] - right) * (int64_t)(x[s + 1] - x[s]);
                left += w[s];
                right -= w[s + 1];
                ++ s;
            }
            val[j][i] = acc;
        }
    }

    /* memcpy(a, val[0], n * sizeof(int64_t)); */
    for(i = 0; i < n; ++ i)
        a[i] = val[i][0];

    if(n * (int64_t) n * (int64_t) k < 1000000000)
    {
        for(; 1 < k; --k)
            for(i = n - 1; -1 < i; --i)
            {
                int s;
                a[i] = val[i][0];

                for(s = 1; s < i + 1; ++ s)
                {
                    const int64_t c = a[s - 1] + val[i][s];
                    if(c < a[i]) a[i] = c;
                }
            }

        return a[n - 1];
    }

    for(; 1 < k; -- k)
    {
        int idx = 0;
        memcpy(b, a, n * sizeof(int64_t));

        for(i = 0; i < n; ++ i)
        {
            a[i] = (idx ? b[idx - 1] : 0) + val[i][idx];

            for(; idx < i && b[idx] + val[i][idx + 1] < a[i]; ++ idx)
                a[i] = b[idx] + val[i][idx + 1];

            {
                int s = i;
                for(s = i; idx < s && i < s + 50; -- s)
                {
                    const int64_t v = (s ? b[s - 1] : 0) + val[i][s];
                    if(v < a[i]) a[i] = v;
                }

            }

        }
    }

    return a[n - 1];
}

int main()
{
    printf("%lld", (long long) mining());
    return EXIT_SUCCESS;
}

Mining C++ Solution

#include <bits/stdc++.h>

using namespace std;

#define forn(i, x, n) for(int i = int(x); i <= int(n); ++i)
#define for1(i, n, x) for(int i = int(n); i >= int(x); --i)
#define file ""
#define pb push_back
#define F first
#define S second
#define _bits __builtin_popcountll

typedef long long ll;
typedef long double ld;
typedef pair <int, int> PII;

const int N = 5e3 + 10;         
const ll INF = 1e18;                                           
const int B = 1e9 + 7;                     
                                
int n, k;
ll w[N], m[N], x[N], s[N];
ll d[N][N], cost[N][N];
int at[N][N];

ll f(int l, int r, int i) {
	ll cur = (s[i] - s[l - 1]) * x[i] - (m[i] - m[l - 1]);
	return cur + (m[r] - m[i]) - (s[r] - s[i]) * x[i];
}

int main() {
#ifdef machine42
	freopen(file"in", "r", stdin);
	freopen(file"out", "w", stdout);
#endif
	ios_base :: sync_with_stdio (0);
	cin.tie(0);

	cin >> n >> k;
	forn(i, 1, n) {
		cin >> x[i] >> w[i];
        s[i] = s[i - 1] + w[i];
        m[i] = m[i - 1] + w[i] * x[i];
    }        

	forn(l, 1, n) {
		int ptr = l;
		forn(r, l, n) {
			while (ptr < r && f(l, r, ptr) >= f(l, r, ptr + 1)) ++ptr;
			cost[l][r] = f(l, r, ptr);	                        
		}
	}    

	d[0][0] = 0;
	forn(i, 1, k)
		d[0][i] = INF;	
	forn(i, 1, n) {
		d[i][0] = INF; 
		at[i][k + 1] = i - 1;
		for1(j, k, 1) {	
			d[i][j] = INF;
			forn(p, at[i - 1][j], at[i][j + 1]) {
				if (d[i][j] >= d[p][j - 1] + cost[p + 1][i]) {
					d[i][j] = d[p][j - 1] + cost[p + 1][i];
					at[i][j] = p;
				}	
			}
			assert(at[i][j] >= at[i - 1][j]);
			if (j < k) assert(at[i][j] <= at[i][j + 1]);
		}            
	}

	cout << d[n][k] << "\n";

	return 0;
}
	

Mining C Sharp Solution

using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;

public class Solver
{
    int n, m;
    long[][] dp, cost;
    void Fun(int d, int l, int r, int ol, int or)
    {
        if (l > r)
            return;
        if (l == r)
        {
            for (int i = ol; i <= or && i < l; i++)
                if (dp[d - 1][i] < long.MaxValue)
                    dp[d][l] = Math.Min(dp[d][l], dp[d - 1][i] + cost[i][l - i - 1]);
            return;
        }

        int mid = (l + r) / 2;
        int ob = -1;
        for (int i = ol; i <= or && i < mid; i++)
            if (dp[d - 1][i] < long.MaxValue && dp[d][mid] > dp[d - 1][i] + cost[i][mid - i - 1])
            {
                dp[d][mid] = dp[d - 1][i] + cost[i][mid - i - 1];
                ob = i;
            }

        Fun(d, l, mid - 1, ol, ob);
        Fun(d, mid + 1, r, ob, or);
    }

    public void Solve()
    {
        n = ReadInt();
        m = ReadInt();
        
        var x = new int[n];
        var a = new int[n];
        for (int i = 0; i < n; i++)
        {
            x[i] = ReadInt();
            a[i] = ReadInt();
        }

        //n = m = 5000;
        //x = Enumerable.Range(1, n).ToArray();
        //a = Enumerable.Range(1, n).ToArray();

        cost = new long[n][];
        for (int i = 0; i < n; i++)
        {
            cost[i] = new long[n - i];
            int p = i;
            long left = 0, right = 0, wleft = 0, wright = 0;
            for (int j = i + 1; j < n; j++)
            {
                wright += a[j];
                right += 1L * a[j] * (x[j] - x[p]);
                while (p < j)
                {
                    if (left + right < left + (wleft + a[p]) * (x[p + 1] - x[p]) + right - wright * (x[p + 1] - x[p]))
                        break;
                    wleft += a[p];
                    left += wleft * (x[p + 1] - x[p]);
                    right -= wright * (x[p + 1] - x[p]);
                    wright -= a[p + 1];
                    p++;
                }
                cost[i][j - i] = left + right;
            }
        }

        dp = new long[m + 1][];
        for (int i = 0; i <= m; i++)
        {
            dp[i] = new long[n + 1];
            for (int j = 0; j <= n; j++)
                dp[i][j] = long.MaxValue;
        }
        dp[0][0] = 0;

        for (int i = 1; i <= m; i++)
            Fun(i, i, n, i - 1, n - 1);
        //for (int i = 0; i < n; i++)
        //    for (int j = 0; j < m; j++)
        //        if (dp[i, j] < long.MaxValue)
        //            for (int k = i + 1; k <= n; k++)
        //                dp[k, j + 1] = Math.Min(dp[k, j + 1], dp[i, j] + cost[i, k - 1]);

        Write(dp[m][n]);
    }

    #region Main

    protected static TextReader reader;
    protected static TextWriter writer;
    static void Main()
    {
#if DEBUG
        reader = new StreamReader("..\\..\\input.txt");
        //reader = new StreamReader(Console.OpenStandardInput());
        writer = Console.Out;
        //writer = new StreamWriter("..\\..\\output.txt");
#else
        reader = new StreamReader(Console.OpenStandardInput());
        writer = new StreamWriter(Console.OpenStandardOutput());
        //reader = new StreamReader("input.txt");
        //writer = new StreamWriter("output.txt");
#endif
        try
        {
            new Solver().Solve();
            //var thread = new Thread(new Solver().Solve, 1024 * 1024 * 128);
            //thread.Start();
            //thread.Join();
        }
        catch (Exception ex)
        {
#if DEBUG
            Console.WriteLine(ex);
#else
            throw;
#endif
        }
        reader.Close();
        writer.Close();
    }

    #endregion

    #region Read / Write
    private static Queue<string> currentLineTokens = new Queue<string>();
    private static string[] ReadAndSplitLine() { return reader.ReadLine().Split(new[] { ' ', '\t', }, StringSplitOptions.RemoveEmptyEntries); }
    public static string ReadToken() { while (currentLineTokens.Count == 0)currentLineTokens = new Queue<string>(ReadAndSplitLine()); return currentLineTokens.Dequeue(); }
    public static int ReadInt() { return int.Parse(ReadToken()); }
    public static long ReadLong() { return long.Parse(ReadToken()); }
    public static double ReadDouble() { return double.Parse(ReadToken(), CultureInfo.InvariantCulture); }
    public static int[] ReadIntArray() { return ReadAndSplitLine().Select(int.Parse).ToArray(); }
    public static long[] ReadLongArray() { return ReadAndSplitLine().Select(long.Parse).ToArray(); }
    public static double[] ReadDoubleArray() { return ReadAndSplitLine().Select(s => double.Parse(s, CultureInfo.InvariantCulture)).ToArray(); }
    public static int[][] ReadIntMatrix(int numberOfRows) { int[][] matrix = new int[numberOfRows][]; for (int i = 0; i < numberOfRows; i++)matrix[i] = ReadIntArray(); return matrix; }
    public static int[][] ReadAndTransposeIntMatrix(int numberOfRows)
    {
        int[][] matrix = ReadIntMatrix(numberOfRows); int[][] ret = new int[matrix[0].Length][];
        for (int i = 0; i < ret.Length; i++) { ret[i] = new int[numberOfRows]; for (int j = 0; j < numberOfRows; j++)ret[i][j] = matrix[j][i]; } return ret;
    }
    public static string[] ReadLines(int quantity) { string[] lines = new string[quantity]; for (int i = 0; i < quantity; i++)lines[i] = reader.ReadLine().Trim(); return lines; }
    public static void WriteArray<T>(IEnumerable<T> array) { writer.WriteLine(string.Join(" ", array)); }
    public static void Write(params object[] array) { WriteArray(array); }
    public static void WriteLines<T>(IEnumerable<T> array) { foreach (var a in array)writer.WriteLine(a); }
    private class SDictionary<TKey, TValue> : Dictionary<TKey, TValue>
    {
        public new TValue this[TKey key]
        {
            get { return ContainsKey(key) ? base[key] : default(TValue); }
            set { base[key] = value; }
        }
    }
    private static T[] Init<T>(int size) where T : new() { var ret = new T[size]; for (int i = 0; i < size; i++)ret[i] = new T(); return ret; }
    #endregion
}

Mining Java Solution

import java.io.*;
import java.util.*;

public class Solution {

  static long chase2(long dpij0, long dpij1, long[][] cost, int j0, int j1) {
    long l = j1 + 1;
    long h = cost.length;
    while (l < h) {
      int m = (int) (l + h >> 1);
      if (dpij0 + cost[j0][m] < dpij1 + cost[j1][m]) {
        l = m + 1;
      } else {
        h = m;
      }
    }
    return l;
  }

  static long mining(int k, int[] x, int[] w) {
    long[][] cost = new long[x.length][x.length];
    long[] dp1 = new long[x.length];
    long[] dp2 = new long[x.length];
    long sumi = 0;
    long sumi2 = 0;
    for (int i = 0; i < x.length; i++) {
      int ki = i;
      long sumk = sumi;
      long sumk2 = sumi2;
      long sumj = sumi;
      long sumj2 = sumi2;
      for (int j = i; j < x.length; j++) {
        sumj += w[j];
        sumj2 += (long)w[j]*x[j];
        for (; ki < j && x[ki]-x[i] < x[j]-x[ki]; ki++) {
          sumk += w[ki];
          sumk2 += (long)w[ki]*x[ki];
        }
        cost[i][j] = sumk2-sumi2-(sumk-sumi)*x[i] + (sumj-sumk)*x[j]-sumj2+sumk2;
      }
      sumi += w[i];
      sumi2 += (long)w[i]*x[i];
      dp1[i] = sumi*x[i]-sumi2;
    }
    int[] q = new int[x.length];
    for (int i = 0; i < k-1; i++) {
      int hd = 0;
      int tl = 0;
      for (int j = 0; j < q.length; j++) {
        while (hd+1 < tl && dp1[q[hd]]+cost[q[hd]][j] > dp1[q[hd+1]]+cost[q[hd+1]][j]) {
          hd++;
        }
        dp2[j] = j != 0 ? dp1[q[hd]]+cost[q[hd]][j] : 0;
        while (hd <= tl - 2 && chase2(dp1[q[tl - 2]], dp1[q[tl - 1]], cost, q[tl - 2],
            q[tl - 1]) > chase2(dp1[q[tl - 1]], dp1[j], cost, q[tl - 1], j)) {
          tl--;
        }
        q[tl++] = j;
      }
      long[] t = dp1;
      dp1 = dp2;
      dp2 = t;
    }
    long ans = Long.MAX_VALUE;
    long sum = sumi;
    long sum2 = sumi2;
    sumi = sumi2 = 0;
    for (int i = 0; i < x.length; i++) {
      ans = Math.min(ans, dp1[i]+sum2-sumi2-(sum-sumi)*x[i]);
      sumi += w[i];
      sumi2 += (long)w[i]*x[i];
    }
    return ans;
  }

  public static void main(String[] args) throws IOException {
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    BufferedWriter bw = new BufferedWriter(new FileWriter(System.getenv("OUTPUT_PATH")));

    StringTokenizer st = new StringTokenizer(br.readLine());
    int n = Integer.parseInt(st.nextToken());
    int k = Integer.parseInt(st.nextToken());

    int[] x = new int[n];
    int[] w = new int[n];
    for (int i = 0; i < n; i++) {
      st = new StringTokenizer(br.readLine());
      x[i] = Integer.parseInt(st.nextToken());
      w[i] = Integer.parseInt(st.nextToken());
    }

    long result = mining(k, x, w);

    bw.write(String.valueOf(result));
    bw.newLine();

    bw.close();
    br.close();
  }
}
c C# C++ HackerRank Solutions java javascript python CcppCSharpHackerrank Solutionsjavajavascriptpython

Post navigation

Previous post
Next post
  • HackerRank Dynamic Array Problem Solution
  • HackerRank 2D Array – DS Problem Solution
  • Hackerrank Array – DS Problem Solution
  • Von Neumann and Harvard Machine Architecture
  • Development of Computers
©2025 THECSICENCE | WordPress Theme by SuperbThemes