Daily Dose of DSA - Day 21
Ninja's Training using RecursiveDP(Top-Bottom)(TC:O(3*4*n)&SC:O(4*n)+O(n)call stack)&Using Iterative DP(Bottom-Up)(TC:O(3*4*n)&SC:O(4*n) O(1)(sp.opt)
Question Link: https://www.codingninjas.com/studio/problems/ninja-s-training_3621003?leftPanelTab=0
Using Recursive DP(Top-Bottom):
The function
rec
is defined to find the maximum score up to a specificindex
given that the task ati+1
index was done last.The function uses a memoization technique with the help of the
dp
array. Thedp
array stores the maximum scores calculated for each index, allowing us to reuse the results and avoid redundant recursive calls.The base case of the recursion is when
index
is 0. In this case, the function calculates the maximum score for the first index by considering all possible tasks (0, 1, and 2) except the one done at the next index (last
). The maximum score is stored in thedp
array at the corresponding index and returned.If the maximum score for the current
index
has already been calculated and stored in thedp
array, the function directly returns the stored value, eliminating the need for further recursive calls.Inside the function, a variable
maxi
is initialized to keep track of the maximum score obtained up to the current index.The function iterates over the three possible tasks (0, 1, and 2) excluding the task done at the
index+1
position (last
).For each task, it calculates the score by adding the points obtained for the task at the current
index
(points[index][i]
) with the maximum score obtained recursively for the previous index (rec(index-1, i, points, dp)
).The function updates
maxi
by taking the maximum value betweenmaxi
and the calculated score. This step ensures thatmaxi
stores the maximum score obtained by considering different tasks at the current index.The function stores
maxi
in thedp
array at the corresponding index (dp[index]
) for future use.Finally, the function returns the maximum score obtained at the last index (
dp[n-1]
), wheren
is the total number of indices in the given input.
int rec(int index , int last, vector<vector<int>> &points,vector<int>&dp)
{
if(index==0) //base case
{
int maxi2 = 0;
for(int i=0;i<=2;i++)
{
if(i!=last)
maxi2 = max(maxi2,points[0][i]);
}
dp[index] = maxi2;
return dp[index];
}
if(dp[index]!=-1) return dp[index]; //To avoid redundancies
int maxi = 0 ;
for(int i=0;i<=2;i++)
{
if(i!=last)
{
int score = points[index][i] + rec(index-1,i,points,dp);
maxi = max(maxi,score);
}
}
dp[index]= maxi;
return dp[index];
}
Using Iterative DP (Bottom-Up):
The
ninjaTraining
function receives the number of rowsn
and the 2D vectorpoints
representing the points scored for different tasks at each index.It initializes a 2D dynamic programming array
dp
of sizen
by 4, wheredp[i][j]
represents the maximum score up to indexi
with the task at indexi+1
done last.The initial values of the
dp
array are set based on the points scored in the first row of thepoints
vector. For example,dp[0][0]
is set to the maximum value betweenpoints[0][1]
andpoints[0][2]
,dp[0][1]
is set to the maximum value betweenpoints[0][0]
andpoints[0][2]
,dp[0][2]
is set to the maximum value betweenpoints[0][0]
andpoints[0][1]
, anddp[0][3]
is set to the maximum value amongpoints[0][0]
,points[0][1]
, andpoints[0][2]
.The function iterates from index
1
ton-1
, representing the remaining rows of thepoints
vector.For each index and each possible last task, represented by the variable
last
(ranging from0
to3
), the maximum score is calculated. The maximum score is determined by iterating over the three possible tasks (0
,1
, and2
) and adding the points obtained for the task at the current index (points[index][i]
) with the maximum score obtained previously for the task at indexi
(dp[index-1][i]
). The maximum of these scores is stored in themaxi
variable.The
dp[index][last]
value is updated with the maximum score obtained for the currentlast
.After calculating the maximum scores for all possible last tasks at the current index, the function moves on to the next index.
Finally, the function returns
dp[n-1][3]
, which represents the maximum score considering any task done last at the last index.
#include<bits/stdc++.h>
using namespace std;
int ninjaTraining(int n, vector<vector<int>>&points)
{
vector<vector<int>> dp(n,vector<int>(4,0));
dp[0][0] = max(points[0][1],points[0][2]);
dp[0][1] = max(points[0][0],points[0][2]);
dp[0][2] = max(points[0][0],points[0][1]);
dp[0][3] = max({points[0][0],points[0][1],points[0][2]});
for(int index=1;index<n;index++)
{
for(int last=0;last<4;last++)
{
dp[index][last] = 0;
int maxi = 0;
for(int i=0;i<3;i++)
{
if(i!=last)
{
int score = points[index][i] + dp[index-1][i];
maxi = max(maxi,score);
}
}
dp[index][last] = maxi;
}
}
return dp[n-1][3];
}
Using Sp.Optimization in Iterative DP:
The
ninjaTraining
function receives the number of rowsn
and the 2D vectorpoints
representing the points scored for different tasks at each index.It initializes a vector
dp
of size 4, wheredp[i]
represents the maximum score considering the task done at indexi+1
last.The initial values of the
dp
vector are set based on the points scored in the first row of thepoints
vector. For example,dp[0]
is set to the maximum value betweenpoints[0][1]
andpoints[0][2]
,dp[1]
is set to the maximum value betweenpoints[0][0]
andpoints[0][2]
,dp[2]
is set to the maximum value betweenpoints[0][0]
andpoints[0][1]
, anddp[3]
is set to the maximum value amongpoints[0][0]
,points[0][1]
, andpoints[0][2]
.The function iterates from index 1 to n-1, representing the remaining rows of the
points
vector.For each index, a temporary vector
temp
is created to store the updated maximum scores.For each possible last task, represented by the variable
last
(ranging from 0 to 3), the maximum score is calculated. The maximum score is determined by iterating over the three possible tasks (0, 1, and 2) and adding the points obtained for the task at the current index (points[index][i]
) with the maximum score obtained previously for the task at indexi
(dp[i]
). The maximum of these scores is stored in themaxi
variable.The value of
temp[last]
is updated with the maximum score obtained for the currentlast
.After calculating the maximum scores for all possible last tasks at the current index, the
dp
vector is updated by assigningtemp
to it. This ensures that the maximum scores for the next iteration are calculated correctly based on the updated values.Finally, the function returns
dp[3]
, which represents the maximum score considering any task done last at the last index.
#include <bits/stdc++.h>
using namespace std;
int ninjaTraining(int n, vector<vector<int>>& points)
{
vector<int> dp(4, 0);
dp[0] = max(points[0][1], points[0][2]);
dp[1] = max(points[0][0], points[0][2]);
dp[2] = max(points[0][0], points[0][1]);
dp[3] = max({ points[0][0], points[0][1], points[0][2] });
for (int index = 1; index < n; index++)
{
vector<int> temp(4, 0);
for (int last = 0; last < 4; last++)
{
int maxi = 0;
for (int i = 0; i < 3; i++)
{
if (i != last)
{
int score = points[index][i] + dp[i];
maxi = max(maxi, score);
}
}
temp[last] = maxi;
}
dp = temp;
}
return dp[3];
}