简体   繁体   中英

Making Maximum Length Ascending Sub array from an array with only 3 valid moves

I need to solve this problem with DP and here is the problem: we have an array and we want to make a ascending sub array with maximum size with 2 conditions:

  1. We can just traverse the array one time from left to right.
  2. We have just two valid moves to make this sub array :
    • We can ignore the next element in array in the traverse
    • We can put the next element at the end or start of the array and that array must be in ascending order

for .eg:

input : arr[ ] = {0 , 3 , 10 , 7 , 6 , 5 , 14}

output : 5

and the Sub array is {5 , 6, , 7 , 10 , 14}

The solution for this instance is, start with 10 and then put 7 in the left and 6 and 5 to the left then put 14 in the right of 10

It means we can extend the array by this conditions from left and right

Well this is a classical dp problem, quite simple to do with top-down approach.

let's define our state dp[c][dec][inc] - we are now looking at element at position c, the element at the back of the sequence we built is at position dec, and the element at the front of the sequence is at position inc.

So now we can traverse to:

  • dp[c+1][dec][inc] by skipping current element
  • dp[c+1][c][inc] by putting current lement at the back (only valid if a[c] <= a[dec])
  • dp[c+1][dec][c] by putting current lement at the front (only valid if a[c] >= a[inc])

sample code (C++) :

const int n = 7;
int a[] = {0, 0, 3, 10, 7, 6, 5, 14};
int dp[n+1][n+1][n+1];

int solve(int c, int dec, int inc)
{
    if(c > n)return 0;
    if(dp[c][dec][inc] != -1)return dp[c][dec][inc];

    dp[c][dec][inc] = solve(c+1,dec,inc); //skip element
    if(inc==0 && dec==0) //if our sequence is empty, try appending element to sequence
        dp[c][dec][inc] = max(dp[c][dec][inc], 1 + solve(c+1,c,c));
    else if(a[c] >= a[inc])//we can extend our array [dec, ..., inc] because current element can be put to front
        dp[c][dec][inc] = max(dp[c][dec][inc], 1 + solve(c+1,dec,c));
    else if(a[c] <= a[dec])//we can extend our array [dec, ..., inc] because current element can be put to back
        dp[c][dec][inc] = max(dp[c][dec][inc], 1 + solve(c+1,c,inc));

    return dp[c][dec][inc];
}

int main()
{
    memset(dp, -1, sizeof dp);
    cout<<solve(1,0,0);
}

Complexity O(n^3)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM