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 X−Y, while Jiro tries to minimize X−Y.
Assuming that the two players play optimally, find the resulting value of X−Y.
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 X−Y, while Jiro tries to minimize X−Y.
Assuming that the two players play optimally, find the resulting value of X−Y.
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:
- if he chooses arr[i], the result will be arr[i] - ans(arr[i+1...j]).
- 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:
- if he chooses arr[i], the result will be arr[i] - ans(arr[i+1...j]).
- 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:
- if he chooses arr[i], the result will be arr[i] - ans(arr[i+1...j]).
- 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