Added a new folder in C++ section(geometry) and added a new problem In dp section
parent
d3590720cf
commit
a22540c838
|
@ -0,0 +1,28 @@
|
||||||
|
{
|
||||||
|
"tasks": [
|
||||||
|
{
|
||||||
|
"type": "cppbuild",
|
||||||
|
"label": "C/C++: g++.exe build active file",
|
||||||
|
"command": "C:\\MinGW\\bin\\g++.exe",
|
||||||
|
"args": [
|
||||||
|
"-fdiagnostics-color=always",
|
||||||
|
"-g",
|
||||||
|
"${file}",
|
||||||
|
"-o",
|
||||||
|
"${fileDirname}\\${fileBasenameNoExtension}.exe"
|
||||||
|
],
|
||||||
|
"options": {
|
||||||
|
"cwd": "${fileDirname}"
|
||||||
|
},
|
||||||
|
"problemMatcher": [
|
||||||
|
"$gcc"
|
||||||
|
],
|
||||||
|
"group": {
|
||||||
|
"kind": "build",
|
||||||
|
"isDefault": true
|
||||||
|
},
|
||||||
|
"detail": "Task generated by Debugger."
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"version": "2.0.0"
|
||||||
|
}
|
|
@ -0,0 +1,108 @@
|
||||||
|
/*
|
||||||
|
Problem Statement: Rod Cutting Problem
|
||||||
|
|
||||||
|
Q. We are given a rod of size ‘N’. It can be cut into pieces. Each length of a piece has a particular price given by the price array. Our task is to find the maximum revenue that can be generated by selling the rod after cutting( if required) into pieces.
|
||||||
|
|
||||||
|
Space Optimization
|
||||||
|
|
||||||
|
If we closely look the relation,
|
||||||
|
|
||||||
|
dp[ind][length] = max(dp[ind-1][length] ,dp[ind][length-(ind+1)])
|
||||||
|
|
||||||
|
We see that to calculate a value of a cell of the dp array, we need only the previous row values (say prev). So, we don’t need to store an entire array. Hence we can space optimize it.
|
||||||
|
|
||||||
|
We will be space optimizing this solution using only one row.
|
||||||
|
|
||||||
|
|
||||||
|
Intuition:
|
||||||
|
If we clearly see the values required: dp[ind-1][cap] and dp[ind-1][cap – wt[ind]], we can say that if we are at a column cap, we will only require the values shown in the blue box(of the same column) from the previous row and other values will be from the cur row itself. So why do we need to store an entire array for it?
|
||||||
|
|
||||||
|
If we need only one value from the prev row, there is no need to store an entire row. We can work a bit smarter.
|
||||||
|
|
||||||
|
We can use the cur row itself to store the required value in the following way:
|
||||||
|
|
||||||
|
1.We somehow make sure that the previous value( say preValue) is available to us in some manner ( we will discuss later how we got the value).
|
||||||
|
|
||||||
|
2.Now, let us say that we want to find the value of cell cur[3], by going through the relation we find that we need a preValue and one value from the cur row.
|
||||||
|
|
||||||
|
3.We see that to calculate the cur[3] element, we need only a single variable (preValue). The catch is that we can initially place this preValue at the position cur[3] (before finding its updated value) and later while calculating for the current row’s cell cur[3], the value present there automatically serves as the preValue and we can use it to find the required cur[3] value. ( If there is any confusion please see the code).
|
||||||
|
|
||||||
|
4.After calculating the cur[3] value we store it at the cur[3] position so this cur[3] will automatically serve as preValue for the next row. In this way we space optimize the tabulation approach by just using one row.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <bits/stdc++.h>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
int cutRodUtil(vector<int>& price, int ind, int N, vector<vector<int>>& dp){
|
||||||
|
|
||||||
|
if(ind == 0){
|
||||||
|
return N*price[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
if(dp[ind][N]!=-1)
|
||||||
|
return dp[ind][N];
|
||||||
|
|
||||||
|
int notTaken = 0 + cutRodUtil(price,ind-1,N,dp);
|
||||||
|
|
||||||
|
int taken = INT_MIN;
|
||||||
|
int rodLength = ind+1;
|
||||||
|
if(rodLength <= N)
|
||||||
|
taken = price[ind] + cutRodUtil(price,ind,N-rodLength,dp);
|
||||||
|
|
||||||
|
return dp[ind][N] = max(notTaken,taken);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int cutRod(vector<int>& price,int N) {
|
||||||
|
|
||||||
|
vector<int> cur (N+1,0);
|
||||||
|
|
||||||
|
for(int i=0; i<=N; i++){
|
||||||
|
cur[i] = i*price[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int ind=1; ind<N; ind++){
|
||||||
|
for(int length =0; length<=N; length++){
|
||||||
|
|
||||||
|
int notTaken = 0 + cur[length];
|
||||||
|
|
||||||
|
int taken = INT_MIN;
|
||||||
|
int rodLength = ind+1;
|
||||||
|
if(rodLength <= length)
|
||||||
|
taken = price[ind] + cur[length-rodLength];
|
||||||
|
|
||||||
|
cur[length] = max(notTaken,taken);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return cur[N];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
|
||||||
|
vector<int> price = {2,5,7,8,10};
|
||||||
|
|
||||||
|
int n = price.size();
|
||||||
|
|
||||||
|
cout<<"The Maximum price generated is "<<cutRod(price,n);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Output: The Maximum price generated is 12
|
||||||
|
|
||||||
|
Time Complexity: O(N*N)
|
||||||
|
|
||||||
|
Reason: There are two nested loops.
|
||||||
|
|
||||||
|
Space Complexity: O(N)
|
||||||
|
|
||||||
|
Reason: We are using an external array of size ‘N+1’ to store only one row.
|
||||||
|
|
||||||
|
*/
|
|
@ -0,0 +1,128 @@
|
||||||
|
/*
|
||||||
|
Given a set of points in the plane. the convex hull of the set is the smallest convex polygon that contains all the points of it.
|
||||||
|
|
||||||
|
|
||||||
|
Algorithm:
|
||||||
|
Step 1) Initialize p as leftmost point.
|
||||||
|
Step 2) Do following while we don’t come back to the first (or leftmost) point.
|
||||||
|
2.1) The next point q is the point, such that the triplet (p, q, r) is counter clockwise for any other point r.
|
||||||
|
|
||||||
|
To find this, we simply initialize q as next point, then we traverse through all points.
|
||||||
|
|
||||||
|
For any point i, if i is more counter clockwise, i.e., orientation(p, i, q) is counter clockwise, then we update q as i.
|
||||||
|
|
||||||
|
Our final value of q is going to be the most counter clockwise point.
|
||||||
|
2.2) next[p] = q (Store q as next of p in the output convex hull).
|
||||||
|
2.3) p = q (Set p as q for next iteration).
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// A C++ program to find convex hull of a set of points. Refer
|
||||||
|
|
||||||
|
#include <bits/stdc++.h>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
struct Point
|
||||||
|
{
|
||||||
|
int x, y;
|
||||||
|
};
|
||||||
|
|
||||||
|
// To find orientation of ordered triplet (p, q, r).
|
||||||
|
// The function returns following values
|
||||||
|
// 0 --> p, q and r are collinear
|
||||||
|
// 1 --> Clockwise
|
||||||
|
// 2 --> Counterclockwise
|
||||||
|
int orientation(Point p, Point q, Point r)
|
||||||
|
{
|
||||||
|
int val = (q.y - p.y) * (r.x - q.x) -
|
||||||
|
(q.x - p.x) * (r.y - q.y);
|
||||||
|
|
||||||
|
if (val == 0) return 0; // collinear
|
||||||
|
return (val > 0)? 1: 2; // clock or counterclock wise
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prints convex hull of a set of n points.
|
||||||
|
void convexHull(Point points[], int n)
|
||||||
|
{
|
||||||
|
// There must be at least 3 points
|
||||||
|
if (n < 3) return;
|
||||||
|
|
||||||
|
// Initialize Result
|
||||||
|
vector<Point> hull;
|
||||||
|
|
||||||
|
// Find the leftmost point
|
||||||
|
int l = 0;
|
||||||
|
for (int i = 1; i < n; i++)
|
||||||
|
if (points[i].x < points[l].x)
|
||||||
|
l = i;
|
||||||
|
|
||||||
|
// Start from leftmost point, keep moving counterclockwise
|
||||||
|
// until reach the start point again. This loop runs O(h)
|
||||||
|
// times where h is number of points in result or output.
|
||||||
|
int p = l, q;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
// Add current point to result
|
||||||
|
hull.push_back(points[p]);
|
||||||
|
|
||||||
|
// Search for a point 'q' such that orientation(p, q,
|
||||||
|
// x) is counterclockwise for all points 'x'. The idea
|
||||||
|
// is to keep track of last visited most counterclock-
|
||||||
|
// wise point in q. If any point 'i' is more counterclock-
|
||||||
|
// wise than q, then update q.
|
||||||
|
q = (p+1)%n;
|
||||||
|
for (int i = 0; i < n; i++)
|
||||||
|
{
|
||||||
|
// If i is more counterclockwise than current q, then
|
||||||
|
// update q
|
||||||
|
if (orientation(points[p], points[i], points[q]) == 2)
|
||||||
|
q = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now q is the most counterclockwise with respect to p
|
||||||
|
// Set p as q for next iteration, so that q is added to
|
||||||
|
// result 'hull'
|
||||||
|
p = q;
|
||||||
|
|
||||||
|
} while (p != l); // While we don't come to first point
|
||||||
|
|
||||||
|
// Print Result
|
||||||
|
for (int i = 0; i < hull.size(); i++)
|
||||||
|
cout << "(" << hull[i].x << ", "
|
||||||
|
<< hull[i].y << ")\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Driver program to test above functions
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
Point points[] = {{0, 3}, {2, 2}, {1, 1}, {2, 1},
|
||||||
|
{3, 0}, {0, 0}, {3, 3}};
|
||||||
|
int n = sizeof(points)/sizeof(points[0]);
|
||||||
|
convexHull(points, n);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
|
||||||
|
Output: The output is points of the convex hull.
|
||||||
|
|
||||||
|
|
||||||
|
(0, 3)
|
||||||
|
(0, 0)
|
||||||
|
(3, 0)
|
||||||
|
(3, 3)
|
||||||
|
|
||||||
|
|
||||||
|
Time Complexity: O(m * n), where n is number of input points and m is number of output or hull points (m <= n). For every point on the hull we examine all the other points to determine the next point.
|
||||||
|
|
||||||
|
Worst case, Time complexity: O(n2). The worst case occurs when all the points are on the hull (m = n).
|
||||||
|
|
||||||
|
Auxiliary Space: O(n), since n extra space has been taken.
|
||||||
|
Set 2- Convex Hull (Graham Scan)
|
||||||
|
|
||||||
|
Note : The above code may produce different results for different order of inputs, when there are collinear points in the convex hull. For example, it produces output as (0, 3) (0, 0) (3, 0) (3, 3) for input (0, 3), (0, 0), (0, 1), (3, 0), (3, 3) and output as (0, 3) (0, 1) (0, 0) (3, 0) (3, 3) for input as (0, 3), (0, 1), (0, 0), (3, 0), (3, 3). We generally need the farthest next point in case of collinear, we can get the desired result in case of collinear points by adding one more if condition.
|
||||||
|
|
||||||
|
*/
|
|
@ -38,6 +38,7 @@
|
||||||
- [0/1-knapsack](Dynamic-Programming/01-knapsack.cpp)
|
- [0/1-knapsack](Dynamic-Programming/01-knapsack.cpp)
|
||||||
- [Matrix chain Multiplication](Dynamic-Programming/matrix-chain-multiplication.cpp)
|
- [Matrix chain Multiplication](Dynamic-Programming/matrix-chain-multiplication.cpp)
|
||||||
- [Edit Distance](Dynamic-Programming/edit-distance.cpp)
|
- [Edit Distance](Dynamic-Programming/edit-distance.cpp)
|
||||||
|
- [Rod Cutting](Dynamic-Programming/rod-cutting.cpp)
|
||||||
|
|
||||||
## Graphs
|
## Graphs
|
||||||
|
|
||||||
|
@ -181,3 +182,7 @@
|
||||||
- [Product of two numbers](Recursion\product-of-numbers.cpp)
|
- [Product of two numbers](Recursion\product-of-numbers.cpp)
|
||||||
- [Product of digits in a number](Recursion\product-of-digits.cpp)
|
- [Product of digits in a number](Recursion\product-of-digits.cpp)
|
||||||
- [Linear search using recursion](Recursion/linear-search.cpp)
|
- [Linear search using recursion](Recursion/linear-search.cpp)
|
||||||
|
|
||||||
|
## Geometry
|
||||||
|
- [Convex Hull](Geometry/convex-hull.cpp)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue