Dynamic Programming Series

Dynamic Programming Series

Day 7

Deque

(AtCoder Problem)

 

Problem Description

Problem Statement

Taro and Jiro will play the following game against each other.

Initially, they are given a sequence a=(a1,a2,,aN). Until a becomes empty, the two players perform the following operation alternately, starting from Taro:

  • Remove the element at the beginning or the end of a. The player earns x points, where x is the removed element.

Let X and Y be Taro's and Jiro's total score at the end of the game, respectively. Taro tries to maximize XY, while Jiro tries to minimize XY.

Assuming that the two players play optimally, find the resulting value of XY.

Example 1:
4
10 80 90 30

Taro: (10, 80, 90,30) → (10, 80, 90)

Problem Description

Problem Statement

Taro and Jiro will play the following game against each other.

Initially, they are given a sequence a=(a1,a2,,aN). Until a becomes empty, the two players perform the following operation alternately, starting from Taro:

  • Remove the element at the beginning or the end of a. The player earns x points, where x is the removed element.

Let X and Y be Taro's and Jiro's total score at the end of the game, respectively. Taro tries to maximize XY, while Jiro tries to minimize XY.

Assuming that the two players play optimally, find the resulting value of XY.

Example 1:
4
10 80 90 30

Taro: (10, 80, 90,30) → (10, 80, 90)

Jiro: (10, 80, 90) → (10, 80)

X Y
30 0
30 90
110 90
110 100

Taro: (10, 80) → (10)

Jiro: (10) → ()

Let us build the thought process for the problem.

Let's take a case when n = 1

10

Taro will play first and take 10 and nothing is left for jiro.

Let us build the thought process for the problem.

Consider n = 2

10 20

Now taro has a choice he can either choose 10 or 20.

 

10 20

Let us build the thought process for the problem.

Consider n = 2

10 20

Now taro has a choice he can either choose 10 or 20.

 

10 20

X = 10

Y = 20

Let us build the thought process for the problem.

Consider n = 2

10 20

Now taro has a choice he can either choose 10 or 20.

 

10 20

X = 10

Y = 20

10 20

OR

X = 20

Y = 10

Let us build the thought process for the problem.

Consider n = 2

10 20

Now taro has a choice he can either choose 10 or 20.

 

10 20

X = 10

Y = 20

10 20

OR

X = 20

Y = 10

Let us build the thought process for the problem.

Consider n = 2

10 20

Now taro has a choice he can either choose 10 or 20.

 

10 20

X = 20

Y = 10

So when n = 2, the first person will obviously choose the max of given numbers

Let us build the thought process for the problem.

Consider n = 3

10 15 30

Let us build the thought process for the problem.

Consider n = 3

10 15 30

If I choose 10 what what would jiro will choose

Taro = 10

Let us build the thought process for the problem.

Consider n = 3

10 15 30

If I choose 10 what what would jiro will choose

For Jiro, the problem reduces to only 2 elements and for n = 2 taro will definitely choose max(15,30) = 30 

Taro = 10

Jiro = 0

Taro

Let us build the thought process for the problem.

Consider n = 3

10 15 30

If I choose 10 what what would jiro will choose

So Jiro will take 30 points with him.

Taro = 10

Jiro = 30

Taro

Jiro

Let us build the thought process for the problem.

Consider n = 3

10 15 30

If I choose 10 what what would jiro will choose

For Taro, Problem reduces to only a single element, and hence he can only take whatever he is left with.

Taro = 10

Jiro = 30

Taro

Jiro

Let us build the thought process for the problem.

Consider n = 3

10 15 30

If I choose 10 what what would jiro will choose

For Taro, Problem reduces to only a single element, and hence he can only take whatever he is left with.

Taro = 25

Jiro = 30

Taro

Jiro

Let us build the thought process for the problem.

Consider n = 3

10 15 30

Oh, I am loosing when I am choosing 10, Let's check for 30

Taro = 30

Jiro = 0

Taro

Let us build the thought process for the problem.

Consider n = 3

10 15 30

Oh, I am loosing when I am choosing 10, Let's check for 30

Taro = 30

Jiro = 0

Taro

Again for Jiro, problem reduces to n = 2 he will choose max(10, 15) = 15

Let us build the thought process for the problem.

Consider n = 3

10 15 30

Oh, I am loosing when I am choosing 10, Let's check for 30

Taro = 30

Jiro = 15

Taro

At last Taro can select 10

Jiro

Let us build the thought process for the problem.

Consider n = 3

10 15 30

I have won for 30 hence I will select 30

Taro = 40

Jiro = 15

Taro

At last Taro can select 10

Jiro

Taro

Let us build the thought process for the problem.

From all these examples what we are trying to understand is that a player has a choice to select an element from beginning or from the last. 

This choice will depend on what the other player will get a score for the remaining subarray.

He will obviously make a move where he is getting

max of (hisScore - opponentScore)

Let's Do it Now.

There are two ways to do it.

1. Recursively trying all to get answer for all subarrays.

Which will be a exponential complexity.

Let's Do it Now.

There are two ways to do it.

1. Recursively trying all to get answer for all subarrays.

Which will be a exponential complexity.

2. Use Memoization to get the answer.

Let's see how we are going to do with memoization.

Let's Do it Now.

For a subarray arr[i...j]

The player has two choices to select:

  1. if he chooses arr[i], the result will be arr[i] - ans(arr[i+1...j]).
  2. if he chooses arr[j], the result will be arr[j] - ans(arr[i...j-1]).

Let's Do it Now.

For a subarray arr[i...j]

The player has two choices to select:

  1. if he chooses arr[i], the result will be arr[i] - ans(arr[i+1...j]).
  2. if he chooses arr[j], the result will be arr[j] - ans(arr[i...j-1]).

Now this answer part is what we are going to store in our DP array.

Let's Do it Now.

For a subarray arr[i...j]

The player has two choices to select:

  1. if he chooses arr[i], the result will be arr[i] - ans(arr[i+1...j]).
  2. if he chooses arr[j], the result will be arr[j] - ans(arr[i...j-1]).

so DP[i][j] = max(arr[i] - DP[i + 1][j], arr[j] - DP[i][j - 1])

We are going to fill this DP array in Bottom Up manner.

Let's Code it.

long long DPGame(vector<long long>& arr) {
    long long n = arr.size();
    vector <vector<long long> > dp(n, vector <long long>(n,0));
    for (int i = 0;i < n;i++)
        dp[i][i] = arr[i];
    for (int d = 1; d < n; d++)
    {
        for (int i = 0;i < n-d;i++)
        {
            dp[i][i+d] = max(arr[i]-dp[i+1][i+d], arr[i+d] - dp[i][i+d-1]);
        }
    }
    return dp[0][n-1];
}

Let's simulate our code for an example.

long long DPGame(vector<long long>& arr) {
    long long n = arr.size();
    vector <vector<long long> > dp(n, vector <long long>(n,0));
    for (int i = 0;i < n;i++)
        dp[i][i] = arr[i];
    for (int d = 1; d < n; d++)
    {
        for (int i = 0;i < n-d;i++)
        {
            dp[i][i+d] = max(arr[i]-dp[i+1][i+d], arr[i+d] - dp[i][i+d-1]);
        }
    }
    return dp[0][n-1];
}

n = 4

10, 80, 90, 30

Let's simulate our code for an example.

long long DPGame(vector<long long>& arr) {
    long long n = arr.size();
    vector <vector<long long> > dp(n, vector <long long>(n,0));
    for (int i = 0;i < n;i++)
        dp[i][i] = arr[i];
    for (int d = 1; d < n; d++)
    {
        for (int i = 0;i < n-d;i++)
        {
            dp[i][i+d] = max(arr[i]-dp[i+1][i+d], arr[i+d] - dp[i][i+d-1]);
        }
    }
    return dp[0][n-1];
}

n = 4

10, 80, 90, 30

Step 1: Construct DP array of size nXn.

   0    1    2      3

   0    1    2      3

Let's simulate our code for an example.

long long DPGame(vector<long long>& arr) {
    long long n = arr.size();
    vector <vector<long long> > dp(n, vector <long long>(n,0));
    for (int i = 0;i < n;i++)
        dp[i][i] = arr[i];
    for (int d = 1; d < n; d++)
    {
        for (int i = 0;i < n-d;i++)
        {
            dp[i][i+d] = max(arr[i]-dp[i+1][i+d], arr[i+d] - dp[i][i+d-1]);
        }
    }
    return dp[0][n-1];
}

n = 4

10, 80, 90, 30

Step 1: Construct DP array of size nXn.

10
80
90
30

   0    1    2      3

   0    1    2      3

Step 2: Fill all the subarray of size 1 with the value itself.

Let's simulate our code for an example.

long long DPGame(vector<long long>& arr) {
    long long n = arr.size();
    vector <vector<long long> > dp(n, vector <long long>(n,0));
    for (int i = 0;i < n;i++)
        dp[i][i] = arr[i];
    for (int d = 1; d < n; d++)
    {
        for (int i = 0;i < n-d;i++)
        {
            dp[i][i+d] = max(arr[i]-dp[i+1][i+d], arr[i+d] - dp[i][i+d-1]);
        }
    }
    return dp[0][n-1];
}

Step 1: Construct DP array of size nXn.

10 70
80
90
30

   0    1    2      3

   0    1    2      3

Step 2: Fill all the subarray of size 1 with the value itself.

Step 3: Now Start filling our matrix as shown.

n = 4

10, 80, 90, 30

Let's simulate our code for an example.

long long DPGame(vector<long long>& arr) {
    long long n = arr.size();
    vector <vector<long long> > dp(n, vector <long long>(n,0));
    for (int i = 0;i < n;i++)
        dp[i][i] = arr[i];
    for (int d = 1; d < n; d++)
    {
        for (int i = 0;i < n-d;i++)
        {
            dp[i][i+d] = max(arr[i]-dp[i+1][i+d], arr[i+d] - dp[i][i+d-1]);
        }
    }
    return dp[0][n-1];
}

Step 1: Construct DP array of size nXn.

10 70
80 10
90
30

   0    1    2      3

   0    1    2      3

Step 2: Fill all the subarray of size 1 with the value itself.

Step 3: Now Start filling our matrix as shown.

n = 4

10, 80, 90, 30

Let's simulate our code for an example.

long long DPGame(vector<long long>& arr) {
    long long n = arr.size();
    vector <vector<long long> > dp(n, vector <long long>(n,0));
    for (int i = 0;i < n;i++)
        dp[i][i] = arr[i];
    for (int d = 1; d < n; d++)
    {
        for (int i = 0;i < n-d;i++)
        {
            dp[i][i+d] = max(arr[i]-dp[i+1][i+d], arr[i+d] - dp[i][i+d-1]);
        }
    }
    return dp[0][n-1];
}

n = 4

10, 80, 90, 30

Step 1: Construct DP array of size nXn.

10 70
80 10
90 60
30

   0    1    2      3

   0    1    2      3

Step 2: Fill all the subarray of size 1 with the value itself.

Step 3: Now Start filling our matrix as shown.

Let's simulate our code for an example.

long long DPGame(vector<long long>& arr) {
    long long n = arr.size();
    vector <vector<long long> > dp(n, vector <long long>(n,0));
    for (int i = 0;i < n;i++)
        dp[i][i] = arr[i];
    for (int d = 1; d < n; d++)
    {
        for (int i = 0;i < n-d;i++)
        {
            dp[i][i+d] = max(arr[i]-dp[i+1][i+d], arr[i+d] - dp[i][i+d-1]);
        }
    }
    return dp[0][n-1];
}

n = 4

10, 80, 90, 30

Step 1: Construct DP array of size nXn.

10 70 20
80 10
90 60
30

   0    1    2      3

   0    1    2      3

Step 2: Fill all the subarray of size 1 with the value itself.

Step 3: Now Start filling our matrix as shown.

Let's simulate our code for an example.

long long DPGame(vector<long long>& arr) {
    long long n = arr.size();
    vector <vector<long long> > dp(n, vector <long long>(n,0));
    for (int i = 0;i < n;i++)
        dp[i][i] = arr[i];
    for (int d = 1; d < n; d++)
    {
        for (int i = 0;i < n-d;i++)
        {
            dp[i][i+d] = max(arr[i]-dp[i+1][i+d], arr[i+d] - dp[i][i+d-1]);
        }
    }
    return dp[0][n-1];
}

n = 4

10, 80, 90, 30

Step 1: Construct DP array of size nXn.

10 70 20
80 10 20
90 60
30

   0    1    2      3

   0    1    2      3

Step 2: Fill all the subarray of size 1 with the value itself.

Step 3: Now Start filling our matrix as shown.

Let's simulate our code for an example.

long long DPGame(vector<long long>& arr) {
    long long n = arr.size();
    vector <vector<long long> > dp(n, vector <long long>(n,0));
    for (int i = 0;i < n;i++)
        dp[i][i] = arr[i];
    for (int d = 1; d < n; d++)
    {
        for (int i = 0;i < n-d;i++)
        {
            dp[i][i+d] = max(arr[i]-dp[i+1][i+d], arr[i+d] - dp[i][i+d-1]);
        }
    }
    return dp[0][n-1];
}

n = 4

10, 80, 90, 30

Step 1: Construct DP array of size nXn.

10 70 20 10
80 10 20
90 60
30

   0    1    2      3

   0    1    2      3

Step 2: Fill all the subarray of size 1 with the value itself.

Step 3: Now Start filling our matrix as shown.

So that's It for Day 7

So that's It for Day 7

Concepts that we have learnt

So that's It for Day 7

We have taken a very first step in Dynamic Programming.

Concepts that we have learnt

1. Game Theory in Dynamic Programming.

So that's It for Day 7

We have taken a very first step in Dynamic Programming.

Concepts that we have learnt

1. Game Theory in Dynamic Programming.

2. Use of optimal Substructure with memoization

So that's It for Day 7

We have taken a very first step in Dynamic Programming.

Concepts that we have learnt

1. Game Theory in Dynamic Programming.

2. Use of optimal Substructure with memoization

Still, Have any Doubts???

Still, Have any Doubts???

Comment it You will get a reply

OR

Send your doubt to email provided in description.

Copy of Day 6 vacation problem

By gauravsahu

Copy of Day 6 vacation problem

  • 51