-
Notifications
You must be signed in to change notification settings - Fork 0
/
NinjaTraining.cpp
136 lines (115 loc) · 3.81 KB
/
NinjaTraining.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#include<bits/stdc++.h>
using namespace std;
/*
* DERIVE A Recurrence Relation by :
* I. -> Try to break down the problem into indices. (Try to map certain parameters into indices)
* II. -> Do STUFF on those INDICES
* III. -> Perform Operations, what's asked in the Question. Ex : Maximize or Minimize.
*
* Example for this Question:-
*
* I. Index -> (Day, LastTask), Where day signify the current Day, and LastTask is the task performed on previous day.
* II. Do Stuff -> Add the current Day's points with subsequent Days using Recursion
* II. Maximize the Answer
*/
int helper(int day, int lastTask, vector<vector<int>> &points) {
if(day == 0){
int maxi = 0;
for(int task = 0; task < 3; task++) {
if(task != lastTask)
maxi = max(maxi, points[0][task]); // * Since this is the last task, take the max.
}
return maxi;
}
int maxi = 0;
for(int task = 0; task < 3; task++) {
if(task != lastTask) {
int point = points[day][task] + helper(day - 1, task, points);
maxi = max(maxi, point);
}
}
return maxi;
}
int ninjaTrainingRecursive(int n, vector<vector<int>> &points)
{
return helper(n-1, 3, points);
}
// * 2D DP Optimized Memoization Solution
// & T.C : O(N*4)*3
// & S.C : O(N) + O(N*4)
int helper(int day, int lastTask, vector<vector<int>> &points, vector<vector<int>> &dp) {
if(day == 0){
int maxi = 0;
for(int task = 0; task < 3; task++) {
if(task != lastTask)
maxi = max(maxi, points[0][task]);
}
cout << "Max is : " << maxi << endl;
return dp[day][lastTask] = maxi;
}
if(dp[day][lastTask] != -1)
return dp[day][lastTask];
int maxi = 0;
for(int task = 0; task < 3; task++) {
if(task != lastTask) {
int point = points[day][task] + helper(day - 1, task, points, dp);
// cout << "Points Returned: " << point << endl;
maxi = max(maxi, point);
}
}
cout << "Max is : " << maxi << endl;
return dp[day][lastTask] = maxi;
}
int ninjaTrainingMemoization(int n, vector<vector<int>> &points)
{
vector<vector<int>> dp(n, vector<int>(4,-1));
return helper(n-1, 3, points, dp);
}
/*
* Tabulation Approach Derivation
* Look for the EXACT BASE Case.
*
* BOTTOM - UP Approach
* I. Create auxillary space as it is from memoization
* II. Initialize the auxillary space with BASE_CASE
*
*/
int ninjaTraining(int n, vector<vector<int>> &points)
{
vector<vector<int>> dp(n, vector<int>(4,-1));
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][1], points[0][0]);
dp[0][3] = max(points[0][0], max(points[0][1], points[0][2]));
for(int day = 1; day < n; day++){
for(int last = 0; last < 4; last++){
dp[day][last] = 0;
for(int task = 0; task < 3; task++){
if(task != last){
int point = points[day][task] + dp[day-1][task];
dp[day][last] = max(dp[day][last], point);
cout << point << endl;
}
}
}
}
return dp[n-1][3];
}
// * SPACE OPTIMIZATION --> CONSTANT SPACE Approach
int ninjaTraining(int n, vector<vector<int>> &points) {
vector<int> prev(3, 0);
prev[0] = max(points[0][1], points[0][2]);
prev[1] = max(points[0][0], points[0][2]);
prev[2] = max(points[0][1], points[0][0]);
for(int day = 1; day < n; day++) {
vector<int> curr(4, 0);
for(int last = 0; last < 4; last++) {
for(int task = 0; task < 3; task++) {
if(task != last)
curr[last] = max(curr[last], points[day][task] + prev[task]);
}
}
prev = curr;
}
return prev[3];
}