Search code examples
algorithmdynamic-programmingcomputer-science

safe array partition based on some criteria


I am trying to solve this problem. the problem can be summarized as: Given a sequence of integers find no of safe partitions, where safe partitions are defined as:

A safe partition is a partition into subsequences S1,S2,…,SK such that for each valid i, min(Si)≤|Si|≤max(Si)— that is, for each subsequence in this partition, its length is greater or equal to its smallest element and smaller or equal to its largest element. Ex:

Input => 1 6 2 3 4 3 4
Output => 6 partitions

[1],[6,2,3,4,3,4]
[1,6,2],[3,4,3,4]
[1,6,2,3],[4,3,4]
[1],[6,2],[3,4,3,4]
[1],[6,2,3],[4,3,4]
[1,6],[2,3],[4,3,4]

I can probably find out the solution somewhere on internet which includes the code but i am more intrested in finding out the approach to solve this problem so i am asking here what are the points that I am missing in my observation.

These are the things that pop in my mind when I read this problem:

  1. if an element at index i extends a sequence safely its quite possible that it could also be the start of a new sequence.so at every element i am left with two choices whether it extends the sequence or not.

so i think it can be represented mathematically as ,

p(0..N)=1+P(i..N)+P(i+1..N),if A[i] is safe to extend current partition
p(0..N)=1+ p(i..N), if A[i] can't be used to extend 

where P is the partition function. is this reasoning valid? am i missing something?


Solution

  • [I'm having trouble giving a direction without actually giving the solution, because once a person thinks in the right direction then the solution becomes evident. I'll try to highlight some facts which may put a person on the right track.]


    Explicitly enumerating safe partitions is problematic, since there are O(2n) safe partitions. For example in:

    1,N,1,N,1,N ... [N elements]
    

    For this sequence, at any subsequence of length > 1 and the subsequence [1] matches the criteria. The number of safe partitions for such a sequence of length n=2k is 3k-1. To prove that, look at the following

    Base k = 1: f(1) = f(2) = 1

    Step assumption: f(2k) = 3k-1.

    f(2k+1) =
    f(2k+2) = (f(2k) + f(2k-1)) + (f(2k-2) + f(2k-3)) + ... + f(1) + 1
    = 2*(f(2k) + f(2k-2) + .. + f(2)) + 1
    = 2 * (3k-1 + 3k-2 + ... + 1) + 1
    = 2 * (3k - 1) / 2 + 1
    = 3k

    Since enumeration is out of the question, for any reasonable performance, the solution must somehow count without iterating. Since the proof that 1,N,...,1,N has 3k-1 did not have to explicitly enumerate all sequences, its principles can be generalized to any sequence.


    NOTES:

    I have solved similar problems before, so the direction was clear to me. For this question I tried to break my thoughts into something manageable and came up with the thought about complexity. I had a very strong feeling that this is exponential even before writing it down, and trying to prove it. This comes from experience and from seeing other problems. The complexity function felt worse than a Fibbonacci because adding an element to a sequence seemed to be adding at least two elements of smaller sizes (similar to the Fibbonacci sequence). Since Fibbonacci is exponential, so the 1,...,1 partitioning must be exponential. From there went on and analyzed it with a recurrence relation.

    The exact way I reached the solution matches my way of thought. Everybody has a different way of thought that works for them, and they need to develop and find it.

    This is how I came to suspect that the number of safe sequences in tge example was 3k-1:

    I recursively calculated f(2k), with base condition f(1)=f(2)=1. Then for 3:

    [1,N,1]
    [1],[N,1]
    [1,N],[1]
    

    And for 4:

    [1,N,1,N]
    [1],[N,1,N]
    [1,N],[1,N]
    

    Meaning f(3)=f(4)=3. Then I recursively applied

    f(2k+2)=2*(f(2k) + f(2k-2) + .. + f(2)) + 1

    resulting with f(2)=1, f(4)=3, f(6)=9, f(8)=27. This suspiciously looks like 3k-1. Then I simply had to prove that with induction.