Day 7
Deque
(AtCoder Problem)
Problem Description
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:
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
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:
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:
Let's Do it Now.
For a subarray arr[i...j]
The player has two choices to select:
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:
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.