rename Dynamic Programming -> dynamic_programming (#645)

* rename Dynamic Programming -> dynamic_programming

* rename dynamic-programming -> dynamic_programming
This commit is contained in:
Christian Clauss
2019-11-28 13:29:01 +01:00
committed by GitHub
parent fc7e416030
commit 5c241487aa
16 changed files with 0 additions and 0 deletions

View File

@@ -0,0 +1,71 @@
//0-1 Knapsack problem - Dynamic programming
//#include <bits/stdc++.h>
#include <iostream>
using namespace std;
//void Print(int res[20][20], int i, int j, int capacity)
//{
// if(i==0 || j==0)
// {
// return;
// }
// if(res[i-1][j]==res[i][j-1])
// {
// if(i<=capacity)
// {
// cout<<i<<" ";
// }
//
// Print(res, i-1, j-1, capacity-i);
// }
// else if(res[i-1][j]>res[i][j-1])
// {
// Print(res, i-1,j, capacity);
// }
// else if(res[i][j-1]>res[i-1][j])
// {
// Print(res, i,j-1, capacity);
// }
//}
int Knapsack(int capacity, int n, int weight[], int value[])
{
int res[20][20];
for (int i = 0; i < n + 1; ++i)
{
for (int j = 0; j < capacity + 1; ++j)
{
if (i == 0 || j == 0)
res[i][j] = 0;
else if (weight[i - 1] <= j)
res[i][j] = max(value[i - 1] + res[i - 1][j - weight[i - 1]], res[i - 1][j]);
else
res[i][j] = res[i - 1][j];
}
}
// Print(res, n, capacity, capacity);
// cout<<"\n";
return res[n][capacity];
}
int main()
{
int n;
cout << "Enter number of items: ";
cin >> n;
int weight[n], value[n];
cout << "Enter weights: ";
for (int i = 0; i < n; ++i)
{
cin >> weight[i];
}
cout << "Enter values: ";
for (int i = 0; i < n; ++i)
{
cin >> value[i];
}
int capacity;
cout << "Enter capacity: ";
cin >> capacity;
cout << Knapsack(capacity, n, weight, value);
return 0;
}

View File

@@ -0,0 +1,20 @@
//program to check whether a number is an armstrong number or not
#include <iostream.h>
#include <Math.h>
int main()
{
int n, k, d, s = 0;
cout << "Enter a number:";
cin >> n;
k = n;
while (k != 0)
{
d = k % 10;
s += (int)pow(d, 3);
k /= 10;
}
if (s == n)
cout << n << "is an armstrong number";
else
cout << n << "is not an armstrong number";
}

View File

@@ -0,0 +1,128 @@
#include <iostream>
#include <limits.h>
using namespace std;
//Wrapper class for storing an edge
class Edge
{
public:
int src, dst, weight;
};
//Wrapper class for storing a graph
class Graph
{
public:
int vertexNum, edgeNum;
Edge *edges;
//Constructs a graph with V vertices and E edges
Graph(int V, int E)
{
this->vertexNum = V;
this->edgeNum = E;
this->edges = (Edge *)malloc(E * sizeof(Edge));
}
//Adds the given edge to the graph
void addEdge(int src, int dst, int weight)
{
static int edgeInd = 0;
if (edgeInd < this->edgeNum)
{
Edge newEdge;
newEdge.src = src;
newEdge.dst = dst;
newEdge.weight = weight;
this->edges[edgeInd++] = newEdge;
}
}
};
//Utility function to print distances
void print(int dist[], int V)
{
cout << "\nVertex Distance" << endl;
for (int i = 0; i < V; i++)
{
if (dist[i] != INT_MAX)
cout << i << "\t" << dist[i] << endl;
else
cout << i << "\tINF" << endl;
}
}
//The main function that finds the shortest path from given source
//to all other vertices using Bellman-Ford.It also detects negative
//weight cycle
void BellmanFord(Graph graph, int src)
{
int V = graph.vertexNum;
int E = graph.edgeNum;
int dist[V];
//Initialize distances array as INF for all except source
//Intialize source as zero
for (int i = 0; i < V; i++)
dist[i] = INT_MAX;
dist[src] = 0;
//Calculate shortest path distance from source to all edges
//A path can contain maximum (|V|-1) edges
for (int i = 0; i <= V - 1; i++)
for (int j = 0; j < E; j++)
{
int u = graph.edges[j].src;
int v = graph.edges[j].dst;
int w = graph.edges[j].weight;
if (dist[u] != INT_MAX && dist[u] + w < dist[v])
dist[v] = dist[u] + w;
}
//Iterate inner loop once more to check for negative cycle
for (int j = 0; j < E; j++)
{
int u = graph.edges[j].src;
int v = graph.edges[j].dst;
int w = graph.edges[j].weight;
if (dist[u] != INT_MAX && dist[u] + w < dist[v])
{
cout << "Graph contains negative weight cycle. Hence, shortest distance not guaranteed." << endl;
return;
}
}
print(dist, V);
return;
}
//Driver Function
int main()
{
int V, E, gsrc;
int src, dst, weight;
cout << "Enter number of vertices: ";
cin >> V;
cout << "Enter number of edges: ";
cin >> E;
Graph G(V, E);
for (int i = 0; i < E; i++)
{
cout << "\nEdge " << i + 1 << "\nEnter source: ";
cin >> src;
cout << "Enter destination: ";
cin >> dst;
cout << "Enter weight: ";
cin >> weight;
G.addEdge(src, dst, weight);
}
cout << "\nEnter source: ";
cin >> gsrc;
BellmanFord(G, gsrc);
return 0;
}

View File

@@ -0,0 +1,79 @@
/** Print all the Catalan numbers from 0 to n, n being the user input.
* A Catalan number satifies the following two properties:
* C(0) = C(1) = 1; C(n) = sum(C(i).C(n-i-1)), from i = 0 to n-1
* Read more about Catalan numbers here:
https://en.wikipedia.org/wiki/Catalan_number
*/
#include <iostream>
using namespace std;
int *cat; // global array to hold catalan numbers
unsigned long int catalan_dp(int n)
{
/** Using the tabulation technique in dynamic programming,
this function computes the first `n+1` Catalan numbers
Parameter
---------
n: The number of catalan numbers to be computed.
Returns
-------
cat[n]: An array containing the first `n+1` Catalan numbers
*/
// By definition, the first two Catalan numbers are 1
cat[0] = cat[1] = 1;
// Compute the remaining numbers from index 2 to index n, using tabulation
for (int i = 2; i <= n; i++)
{
cat[i] = 0;
for (int j = 0; j < i; j++)
cat[i] += cat[j] * cat[i - j - 1]; // applying the definition here
}
// Return the result
return cat[n];
}
int main(int argc, char *argv[])
{
int n;
cout << "Enter n: ";
cin >> n;
cat = new int[n + 1];
cout << "Catalan numbers from 0 to " << n << " are:\n";
for (int i = 0; i <= n; i++)
{
cout << "catalan (" << i << ") = " << catalan_dp(i) << endl;
// NOTE: Since `cat` is a global array, calling `catalan_dp`
// repeatedly will not recompute the the values already computed
// as in case of pre-computed values, the array will simply return them,
// instead of recomputing them.
}
return 0;
}
/** Sample Test Case:
$ cd "Dynamic Programming"
$ g++ Catalan-Numbers.cpp
$ ./a.exe
Enter n: 5
Catalan numbers from 0 to 5 are:
catalan (0) = 1
catalan (1) = 1
catalan (2) = 2
catalan (3) = 5
catalan (4) = 14
catalan (5) = 42
*/

View File

@@ -0,0 +1,50 @@
#include <iostream>
#include <climits>
using namespace std;
// Function to find the Minimum number of coins required to get Sum S
int findMinCoins(int arr[], int n, int N)
{
// dp[i] = no of coins required to get a total of i
int dp[N + 1];
// 0 coins are needed for 0 sum
dp[0] = 0;
for (int i = 1; i <= N; i++)
{
// initialize minimum number of coins needed to infinity
dp[i] = INT_MAX;
int res = INT_MAX;
// do for each coin
for (int c = 0; c < n; c++)
{
if (i - arr[c] >= 0) // check if coins doesn't become negative by including it
res = dp[i - arr[c]];
// if total can be reached by including current coin c,
// update minimum number of coins needed dp[i]
if (res != INT_MAX)
dp[i] = min(dp[i], res + 1);
}
}
// The Minimum No of Coins Required for N = dp[N]
return dp[N];
}
int main()
{
// No of Coins We Have
int arr[] = {1, 2, 3, 4};
int n = sizeof(arr) / sizeof(arr[0]);
// Total Change Required
int N = 15;
cout << "Minimum Number of Coins Required " << findMinCoins(arr, n, N) << "\n";
return 0;
}

View File

@@ -0,0 +1,28 @@
/*Given a rod of length n inches and an array of prices that
contains prices of all pieces of size smaller than n. Determine
the maximum value obtainable by cutting up the rod and selling
the pieces.*/
#include <bits/stdc++.h>
using namespace std;
int cutrod(int p[], int n)
{
int r[n + 1];
r[0] = 0;
for (int j = 0; j < n; j++)
{
int q = INT_MIN;
for (int i = 0; i <= j; i++)
{
q = max(q, p[i] + r[j - i]);
}
r[j + 1] = q;
}
return r[n];
}
int main()
{
int price[] = {1, 5, 8, 9, 10, 17, 17, 20, 24, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50};
cout << cutrod(price, 30);
return 0;
}

View File

@@ -0,0 +1,94 @@
/* Given two strings str1 & str2
* and below operations that can
* be performed on str1. Find
* minimum number of edits
* (operations) required to convert
* 'str1' into 'str2'/
* a. Insert
* b. Remove
* c. Replace
* All of the above operations are
* of equal cost
*/
#include <iostream>
#include <string>
using namespace std;
int min(int x, int y, int z)
{
return min(min(x, y), z);
}
/* A Naive recursive C++ program to find
* minimum number of operations to convert
* str1 to str2.
* O(3^m)
*/
int editDist(string str1, string str2, int m, int n)
{
if (m == 0)
return n;
if (n == 0)
return m;
//If last characters are same then continue
//for the rest of them.
if (str1[m - 1] == str2[n - 1])
return editDist(str1, str2, m - 1, n - 1);
//If last not same, then 3 possibilities
//a.Insert b.Remove c. Replace
//Get min of three and continue for rest.
return 1 + min(editDist(str1, str2, m, n - 1),
editDist(str1, str2, m - 1, n),
editDist(str1, str2, m - 1, n - 1));
}
/* A DP based program
* O(m x n)
*/
int editDistDP(string str1, string str2, int m, int n)
{
//Create Table for SubProblems
int dp[m + 1][n + 1];
//Fill d[][] in bottom up manner
for (int i = 0; i <= m; i++)
{
for (int j = 0; j <= n; j++)
{
//If str1 empty. Then add all of str2
if (i == 0)
dp[i][j] = j;
//If str2 empty. Then add all of str1
else if (j == 0)
dp[i][j] = i;
//If character same. Recur for remaining
else if (str1[i - 1] == str2[j - 1])
dp[i][j] = dp[i - 1][j - 1];
else
dp[i][j] = 1 + min(dp[i][j - 1], //Insert
dp[i - 1][j], //Remove
dp[i - 1][j - 1] //Replace
);
}
}
return dp[m][n];
}
int main()
{
string str1 = "sunday";
string str2 = "saturday";
cout << editDist(str1, str2, str1.length(), str2.length()) << endl;
cout << editDistDP(str1, str2, str1.length(), str2.length()) << endl;
return 0;
}

View File

@@ -0,0 +1,52 @@
/* Function to get minimun number of trials needed
* in worst case with n eggs and k floors
*/
#include <iostream>
#include <climits>
using namespace std;
int eggDrop(int n, int k)
{
int eggFloor[n + 1][k + 1];
int result;
for (int i = 1; i <= n; i++)
{
eggFloor[i][1] = 1; //n eggs..1 Floor
eggFloor[i][0] = 0; //n eggs..0 Floor
}
// Only one egg available
for (int j = 1; j <= k; j++)
{
eggFloor[1][j] = j;
}
for (int i = 2; i <= n; i++)
{
for (int j = 2; j <= k; j++)
{
eggFloor[i][j] = INT_MAX;
for (int x = 1; x <= j; x++)
{
// 1+max(eggBreak[one less egg, lower floors],
// eggDoesntBreak[same # of eggs, upper floors]);
result = 1 + max(eggFloor[i - 1][x - 1], eggFloor[i][j - x]);
if (result < eggFloor[i][j])
eggFloor[i][j] = result;
}
}
}
return eggFloor[n][k];
}
int main()
{
int n, k;
cout << "Enter number of eggs and floors: ";
cin >> n >> k;
cout << "Minimum number of trials in worst case: " << eggDrop(n, k) << endl;
return 0;
}

View File

@@ -0,0 +1,24 @@
#include <bits/stdc++.h>
using namespace std;
int fib(int n)
{
int res[3];
res[0] = 0;
res[1] = 1;
for (int i = 2; i <= n; i++)
{
res[2] = res[1] + res[0];
res[0] = res[1];
res[1] = res[2];
}
return res[1];
}
int main(int argc, char const *argv[])
{
int n;
cout << "Enter n: ";
cin >> n;
cout << "Fibonacci number is ";
cout << fib(n) << endl;
return 0;
}

View File

@@ -0,0 +1,26 @@
#include <bits/stdc++.h>
using namespace std;
int arr[1000000];
int fib(int n)
{
if (arr[n] == -1)
{
if (n <= 1)
arr[n] = n;
else
arr[n] = fib(n - 1) + fib(n - 2);
}
return arr[n];
}
int main(int argc, char const *argv[])
{
int n;
cout << "Enter n: ";
cin >> n;
for (int i = 0; i < n + 1; ++i)
{
arr[i] = -1;
}
cout << "Fibonacci number is " << fib(n) << endl;
return 0;
}

View File

@@ -0,0 +1,112 @@
#include <iostream>
#include <limits.h>
#include <string.h>
using namespace std;
//Wrapper class for storing a graph
class Graph
{
public:
int vertexNum;
int **edges;
//Constructs a graph with V vertices and E edges
Graph(int V)
{
this->vertexNum = V;
this->edges = (int **)malloc(V * sizeof(int *));
for (int i = 0; i < V; i++)
{
this->edges[i] = (int *)malloc(V * sizeof(int));
for (int j = 0; j < V; j++)
this->edges[i][j] = INT_MAX;
this->edges[i][i] = 0;
}
}
//Adds the given edge to the graph
void addEdge(int src, int dst, int weight)
{
this->edges[src][dst] = weight;
}
};
//Utility function to print distances
void print(int dist[], int V)
{
cout << "\nThe Distance matrix for Floyd - Warshall" << endl;
for (int i = 0; i < V; i++)
{
for (int j = 0; j < V; j++)
{
if (dist[i * V + j] != INT_MAX)
cout << dist[i * V + j] << "\t";
else
cout << "INF"
<< "\t";
}
cout << endl;
}
}
//The main function that finds the shortest path from a vertex
//to all other vertices using Floyd-Warshall Algorithm.
void FloydWarshall(Graph graph)
{
int V = graph.vertexNum;
int dist[V][V];
//Initialise distance array
for (int i = 0; i < V; i++)
for (int j = 0; j < V; j++)
dist[i][j] = graph.edges[i][j];
//Calculate distances
for (int k = 0; k < V; k++)
//Choose an intermediate vertex
for (int i = 0; i < V; i++)
//Choose a source vertex for given intermediate
for (int j = 0; j < V; j++)
//Choose a destination vertex for above source vertex
if (dist[i][k] != INT_MAX && dist[k][j] != INT_MAX && dist[i][k] + dist[k][j] < dist[i][j])
//If the distance through intermediate vertex is less than direct edge then update value in distance array
dist[i][j] = dist[i][k] + dist[k][j];
//Convert 2d array to 1d array for print
int dist1d[V * V];
for (int i = 0; i < V; i++)
for (int j = 0; j < V; j++)
dist1d[i * V + j] = dist[i][j];
print(dist1d, V);
}
//Driver Function
int main()
{
int V, E;
int src, dst, weight;
cout << "Enter number of vertices: ";
cin >> V;
cout << "Enter number of edges: ";
cin >> E;
Graph G(V);
for (int i = 0; i < E; i++)
{
cout << "\nEdge " << i + 1 << "\nEnter source: ";
cin >> src;
cout << "Enter destination: ";
cin >> dst;
cout << "Enter weight: ";
cin >> weight;
G.addEdge(src, dst, weight);
}
FloydWarshall(G);
return 0;
}

View File

@@ -0,0 +1,82 @@
//Longest common subsequence - Dynamic Programming
#include <iostream>
using namespace std;
void Print(int trace[20][20], int m, int n, string a)
{
if (m == 0 || n == 0)
{
return;
}
if (trace[m][n] == 1)
{
Print(trace, m - 1, n - 1, a);
cout << a[m - 1];
}
else if (trace[m][n] == 2)
{
Print(trace, m - 1, n, a);
}
else if (trace[m][n] == 3)
{
Print(trace, m, n - 1, a);
}
}
int lcs(string a, string b)
{
int m = a.length(), n = b.length();
int res[m + 1][n + 1];
int trace[20][20];
// fills up the arrays with zeros.
for (int i = 0; i < m + 1; i++)
{
for (int j = 0; j < n + 1; j++)
{
res[i][j] = 0;
trace[i][j] = 0;
}
}
for (int i = 0; i < m + 1; ++i)
{
for (int j = 0; j < n + 1; ++j)
{
if (i == 0 || j == 0)
{
res[i][j] = 0;
trace[i][j] = 0;
}
else if (a[i - 1] == b[j - 1])
{
res[i][j] = 1 + res[i - 1][j - 1];
trace[i][j] = 1; // 1 means trace the matrix in upper left diagonal direction.
}
else
{
if (res[i - 1][j] > res[i][j - 1])
{
res[i][j] = res[i - 1][j];
trace[i][j] = 2; // 2 means trace the matrix in upwards direction.
}
else
{
res[i][j] = res[i][j - 1];
trace[i][j] = 3; // means trace the matrix in left direction.
}
}
}
}
Print(trace, m, n, a);
return res[m][n];
}
int main()
{
string a, b;
cin >> a >> b;
cout << lcs(a, b);
return 0;
}

View File

@@ -0,0 +1,46 @@
//Program to calculate length of longest increasing subsequence in an array
// in O(n log n)
// tested on : https://cses.fi/problemset/task/1145/
#include <bits/stdc++.h>
using namespace std;
int LIS(int arr[], int n)
{
set < int > active; // The current built LIS.
active.insert(arr[0]);
// Loop through every element.
for (int i = 1; i < n; ++i)
{
auto get = active.lower_bound(arr[i]);
if (get == active.end())
{
active.insert(arr[i]);
} // current element is the greatest so LIS increases by 1.
else
{
int val = * get; // we find the position where arr[i] will be in the LIS. If it is in the LIS already we do nothing
if (val > arr[i])
{
// else we remove the bigger element and add a smaller element (which is arr[i]) and continue;
active.erase(get);
active.insert(arr[i]);
}
}
}
return active.size(); // size of the LIS.
}
int main(int argc, char const * argv[])
{
int n;
cout << "Enter size of array: ";
cin >> n;
int a[n];
cout << "Enter array elements: ";
for (int i = 0; i < n; ++i)
{
cin >> a[i];
}
cout << LIS(a, n) << endl;
return 0;
}

View File

@@ -0,0 +1,39 @@
//Program to calculate length of longest increasing subsequence in an array
#include <bits/stdc++.h>
using namespace std;
int LIS(int a[], int n)
{
int lis[n];
for (int i = 0; i < n; ++i)
{
lis[i] = 1;
}
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < i; ++j)
{
if (a[i] > a[j] && lis[i] < lis[j] + 1)
lis[i] = lis[j] + 1;
}
}
int res = 0;
for (int i = 0; i < n; ++i)
{
res = max(res, lis[i]);
}
return res;
}
int main(int argc, char const *argv[])
{
int n;
cout << "Enter size of array: ";
cin >> n;
int a[n];
cout << "Enter array elements: ";
for (int i = 0; i < n; ++i)
{
cin >> a[i];
}
cout << LIS(a, n) << endl;
return 0;
}

View File

@@ -0,0 +1,62 @@
#include <iostream>
#include <climits>
using namespace std;
#define MAX 10
// dp table to store the solution for already computed sub problems
int dp[MAX][MAX];
// Function to find the most efficient way to multiply the given sequence of matrices
int MatrixChainMultiplication(int dim[], int i, int j)
{
// base case: one matrix
if (j <= i + 1)
return 0;
// stores minimum number of scalar multiplications (i.e., cost)
// needed to compute the matrix M[i+1]...M[j] = M[i..j]
int min = INT_MAX;
// if dp[i][j] is not calculated (calculate it!!)
if (dp[i][j] == 0)
{
// take the minimum over each possible position at which the
// sequence of matrices can be split
for (int k = i + 1; k <= j - 1; k++)
{
// recur for M[i+1]..M[k] to get a i x k matrix
int cost = MatrixChainMultiplication(dim, i, k);
// recur for M[k+1]..M[j] to get a k x j matrix
cost += MatrixChainMultiplication(dim, k, j);
// cost to multiply two (i x k) and (k x j) matrix
cost += dim[i] * dim[k] * dim[j];
if (cost < min)
min = cost; // store the minimum cost
}
dp[i][j] = min;
}
// return min cost to multiply M[j+1]..M[j]
return dp[i][j];
}
// main function
int main()
{
// Matrix i has Dimensions dim[i-1] & dim[i] for i=1..n
// input is 10 x 30 matrix, 30 x 5 matrix, 5 x 60 matrix
int dim[] = {10, 30, 5, 60};
int n = sizeof(dim) / sizeof(dim[0]);
// Function Calling: MatrixChainMultiplications(dimensions_array, starting, ending);
cout << "Minimum cost is " << MatrixChainMultiplication(dim, 0, n - 1) << "\n";
return 0;
}

View File

@@ -0,0 +1,65 @@
#include<bits/stdc++.h>
using namespace std;
int max(int a,int b)
{
return (a > b) ? a : b;
}
int main()
{
char str1[]="DEFBCD";
char str2[]="ABDEFJ";
int i,j,k;
int n=strlen(str1)+1;
int m=strlen(str2)+1;
//cout<<n<<" "<<m<<"\n";
int a[m][n];
for(i=0;i<m;i++)
{
for(j=0;j<n;j++)
{
if(i==0 || j==0)
a[i][j]=0;
else if(str1[i-1] == str2[j-1])
a[i][j]=a[i-1][j-1]+1;
else
a[i][j]=0;
}
}
/*for(i=0;i<m;i++)
{
for(j=0;j<n;j++)
cout<<a[i][j]<<" ";
cout<<"\n";
}*/
int ma=-1;
int indi,indj;
for(i=0;i<m;i++)
{
for(j=0;j<n;j++)
{
if(a[i][j]>ma)
{
ma=a[i][j];
indi=i;
indj=j;
}
}
}
cout<<str1<<"\n";
cout<<str2<<"\n";
cout<<"longest string size = "<<ma/*<<" "<<indi<<" "<<indj*/<<"\n";
for(i=indi-3;i<indi;i++)
cout<<str1[i];
cout<<"\n";
}