3

You have a grid n x n with n rows and n columns. For every column j you are given a number Cj and for every row i you are given a number Ri. You need to mark some points on the grid, in this way:

  • the number of marked points in every row is at most Ri;
  • the number of marked points in every column is at most Cj;
  • you mark the maximum number of points that satify the last two constraints and return this number of points.

The input is: n (dimension of the grid); the sequence of Ri and the sequence of Cj.

for example in this grid the return is 34 example

Find an algorithm in linear time: O(n) or O(n log(n)) with demonstration. I have found a solution with Max-Flow alg. but the complexity is too high.

lorenzo188
  • 31
  • 3

2 Answers2

1

Hints

I suggest iterating over the rows in order from greatest Ri to smallest.

Keep track of how many spaces we have for each column. The number of spaces starts at the given Cj values.

For each row, mark as many points in the grid as are allowed based on the current number of spaces in the columns. Make sure to place points in the columns with the greatest number of spaces first.

Peter de Rivaz
  • 33,126
  • 4
  • 46
  • 75
  • Are you sure this is necessary? The bipartite graph on which the matching is performed is complete, so I don't think the order even matters. – Niklas B. Dec 01 '15 at 12:57
  • 1
    Suppose we had column sums of [2,2,2] and row sums of [2,2,2]. If we did a straightforward greedy algorithm we would reduce the column sums to [1,1,2] and then to [0,0,2], and then find that we cannot assign the values in the last row. – Peter de Rivaz Dec 01 '15 at 13:16
  • this solution is O(n^2) because you are obliged to iterate on the cells of the matrix. You have to return just the number of maximum points without representing them. – lorenzo188 Dec 01 '15 at 17:07
  • @lorenzo188 This approach can be implemented in O(n log n). You just have to place all the elements in a row in one single step (by decrementing the corresponding column values). You might want to use a one-dimensional search data structure for that – Niklas B. Dec 01 '15 at 21:55
  • @NiklasB. can you give me an example with this input: 5 15254 15445 (return = 16). ty – lorenzo188 Dec 02 '15 at 09:38
  • 1
    @lorenzo188 Sort: 55421 55441. Then greedily assign each row by subtracting from the column array: 55441 -> 44330 -> 33220 -> 22110 -> 11110 -> 11100. In total we were able to subtract 16 (5 + 4 + 4 + 2 + 1) – Niklas B. Dec 02 '15 at 10:27
  • @NiklasB. Isn't your algorithm n^2 for this input: 5 55555 55555 (return = 25) ? I think in this case we have n iterations and each iteration has a nested loop that takes n iterations. – lorenzo188 Dec 02 '15 at 14:24
  • 1
    @lorenzo188 You can use more elaborate data structures to reduce the update time per iteration to O(log n). Of course a nested loop is not a very efficient implementation. Basically you need to support the following operations on a set of size n: (1) Find the number of elements that are not zero (2) Decrement each non-zero element by one. A segment tree (full binary search tree) or binary-indexed tree comes to mind – Niklas B. Dec 02 '15 at 19:21
  • @NiklasB. The problem is not to find the element to decrease but the number of decrements that you doing. In the worst case you make n x n decrements O(n^2) – lorenzo188 Dec 03 '15 at 14:27
  • @lorenzo188 Yes you can make Omega(n^2) decrements. You can *compute* the number of possible decrements in O(n log n) though, using a good data structure, and that's all you need. – Niklas B. Dec 03 '15 at 14:30
  • @NiklasB. I'm sorry if i bother you, but i really don't get your point. What do you mean by computing the number of possible decrements? In the last example i wrote, suppose we read the first 5: then we should decrement all the other number by 1 (as you pointed out in your previous comment, "decrement each non-zero element by one"). How is it possible to do it in logn, if we have to decrement all the n elements by one? furthermore for this input 4 3322 3322 your computation is: 3322 -> 2212 -> 1102 -> 0002 -> 0001 and the return is 9 (3+3+2+1) but the maximum in this case is 10. – lorenzo188 Dec 04 '15 at 16:42
  • "How is it possible to do it in logn" By using a clever data structure that supports logarithmic-time range updates, like an augmented self-balancing binary search tree. It's a non-trivial algorithm though, so I'm not going to describe it to you in a comment. The greedy algorithm described by Peter would work differently than what you describe: 3322 -> 2212 -> 1111 -> 0011 -> 0000 You always assign to the columns with largest remaining total – Niklas B. Dec 04 '15 at 16:50
0

@NiklasB. with an augmented self-balancing binary search tree you can decrement one interval by 1 in O(Log n) but how can you find the number of elements that are not zero in minor time of O(n)?In this case for example input 4 3322 3322 3322 -> 2212 -> 1111 -> 0011 -> 0000 You take number 3(the first element of row indicator) and decrement the interval [0,2] of columns by 1 and this cost O(Log n), and the columns indicator are all > 0, but when you arrive at 0011 you must alert that are 2 zero because if you have a 3 in the row you can subtract only 2 if you don't want a number a negative number.If you say the number of zero you can take only interval of n - number of 0.But how you can manage this problem in complexity time that isn't O(n)?

Tidus17
  • 1
  • 1