0

I've got a homework about number sequences. Given array of n elements from 1 to MAX. We can choose any number become start. We can multiply start by 2, or divided it by 2, but if the start is already odd number we can't divided it. The task is we must minimize the total of differences for each number in the array.

For example
arr[]={2,4,7,32,16} The output is 1, because we can choose 1 as the start. For each element we must make this number greater and closer to the elements.

We traverse through the array.
For n=0; The element is 2. So we multiply start by 2, 1 time start=2 so the difference is 2-2=0;
For n=1; The element is 4. So we multiply start by 2, 1 time start=4 so the difference is 4-4=0;
For n=2; The element is 7. So we multiply start by 2, 1 time start=8 so the difference is 8-7=1;
For n=3; The element is 32. So we multiply start by 2, 2 time start=32 so the difference is 32-32=0;
For n=4; The element is 16. So we divided start by 2, 1 time start=16 so the difference is 16-16=0; SO TOTAL DIFFERENCES=0+0+1+0=1;

If we choose start=3 then it becomes
For n=1; The element is 4. So we multiply start by 2, 1 time start=6 so the difference is 6-4=2;
For n=2; The element is 7. So we multiply start by 2, 1 time start=12 so the difference is 12-7=5;
For n=3; The element is 32. So we multiply start by 2, 2 time start=48 so the difference is 48-32=16;
For n=4; The element is 16. So we divided start by 2, 1 time start=24 so the difference is 24-16=8; SO TOTAL DIFFERENCES=2+5+16+8=31;

We can see that for start=1 the output is minimum than all numbers by brute-forcing each number from 1 to MAX.

To solve this problem i've got idea.

  1. For start we choose all odd number from 1 to MAX.
    2. Then i brute-force all the possible start for every elements to get the minimum.

This is the PASCAL code

uses math;
var
  data: array[1..1000100] of longint;
  s: string[7];
  n, i, j, min, ansn, ansb, sub: longint;

  function minimum(a, b: longint): longint;
  begin
    if a > b then
      minimum := b
    else
      minimum := a;
  end;

  function hitung(a: longint): longint;
  var
    x, hit, ca, tot, b: longint;
  begin
    hit := 0;
    tot := 0;
    for x := 1 to n do 
    begin
      hit := hit + data[x];

      b := a;

      while b < data[x] do 
      begin
        b := b * 2;
      end;

      tot := tot + b;
    end;
    hitung := tot - hit;
  end;

begin
  readln(s);
  readln(n);
  sub := 1000000;
  for i := 1 to n do
    read(data[i]);

  ansb:=hitung(1);

  j:=1;

  while ((ansb > 0) and (j <= sub)) do
  begin
    ansn := hitung((2 * (j)) + 1);
    min := minimum(ansb, ansn);
    ansb := min;
    j := j + 1
  end;

  writeln(min);
end.

<br> It works for small MAX but the hint of solution said that the solution is using prefix-sum, with O(MAX/2). While my solution is O(MAX/2*N). I don't know where to insert the prefix sum. How we can do that? Thanks in advance!

Chris
  • 26,361
  • 5
  • 21
  • 42
Zzzz
  • 1
  • 3
  • Any algorithm must at least look at every element from the input. So, an algorithm whose time complexity is independent of `N` cannot exist. – Nico Schertler Jul 24 '15 at 12:55
  • i don't know exactly. but how can we make that algorithm faster? the hint said that we must using prefix sum. How i can do that? – Zzzz Jul 25 '15 at 11:27

0 Answers0