Can't find a range of maximum product subarray - c++

I'm solving Maximum Product Subarray problem on C++. My code finds only a max.product of subarray, but not a range.
I found some explanation here - https://www.geeksforgeeks.org/maximum-product-subarray/ and used the code. How could I find the range(Left index, Right index) of subarray that gives me maximum product? (I found some similar posts here, but all of them on java, and i can't understand them properly)
#include<bits/stdc++.h>
#include <stdio.h>
using namespace std;
int min(int x, int y) {
return (x < y) ? x : y;
}
int max(int x, int y) {
return (x > y) ? x : y;
}
int solve(int a[], int n){
int maxend = 0, minend = 0;
int maxans = 0;
for (int i = 1; i <= n; i++){
int temp = maxend;
maxend = max(a[i], max(a[i] * maxend, a[i] * minend));
minend = min(a[i], min(a[i] * temp, a[i] * minend));
maxans = max(maxans, maxend);
}
return maxans;
}
int main(void){
int n, a[10000];
cin >> n;
for(int i=1; i<=n; i++){
cin >> a[i];
}
cout << solve(a, n);
return 0;
}

If all you need is the range information, you can keep track of the indices where maxans variable changed. That would indicate to you where the maximum product comes from, which would be the right endpoint of the range. Then, after you compute the maxans, you can basically go left until you get the maximum product, at which point you will have found the left interval.
The following implementation can serve as a demonstration.
int solve(int a[], int n){
int maxend = 0, minend = 0;
int maxans = 0;
int max_r = -1;
for (int i = 1; i <= n; i++){
int temp = maxend;
maxend = max(a[i], max(a[i] * maxend, a[i] * minend));
minend = min(a[i], min(a[i] * temp, a[i] * minend));
if(maxans < maxend){
maxans = maxend;
max_r = i;
}
}
int max_l = max_r;
for(int i=1; i < maxans; max_l--){
i = i * a[max_l];
}
//At this point you have the range [max_l, max_r] that yield maxans as the product
return maxans;
}

Related

How to find a mistake in the calculation of the amounts

I tried to complete a task with the calculation of the amounts. The task is Sn=(cosx/1)+((cosx+cos2x)/2)+...+((cosx+...+cosxn)/n);x - float, n - integer.
But the programm outputed zero in every situation.
Its c++ code written on DevC++5.11. I almost finished the code, but i cant find a mistake.
float funct(float x, float s, int n)
{
if (n < 1) {
cout << s;
return 0;
}
for (int i = n; i < 1; i--) {
float a = (cos(i * x)) / n;
s = s + a;
}
return funct(x, s, n - 1);
}
int main(void)
{
float x = 1, s = 0;
int n;
cin >> n;
funct(x, s, n);
}
I expect the output something like terible float numbers, but the actual output is zero.
for (int i = n; i < 1; i--)
Should be
for (int i = 1; i <= n; i++)
if you want it to loop from 1 to n

Errors Within Void Merge

I've been having problems trying to figure out how to fix this code I wrote for Mergesort.
The intended result was to output a sorted array of inputs, but the void merge function contains errors that result in either an unsorted array or an array of really large or small numbers.
I've tried many times to fix them, but the result still doesn't come out perfectly.
Can you look it over and tell me what I've been doing wrong?
#include "pch.h"
#include <iostream>
using namespace std;
void merge(int* arr, int p, int q, int r) {
//copy A[p.q] into L
//and A[q+1.r] into R
int i, j, k;
int n1 = q - p + 1;
int n2 = r - q;
int* L = new int[n1+1];
int* R = new int[n2+1];
for (i = 1; i <= n1; i++) {
L[i] = arr[p+i-1];
}
for (j = 1; j <= n2; j++){
R[j] = arr[q+j];
}
L[n1+1] = 99999;
R[n2+1] = 99999; //represents infinity
i = j = 1;
for (k = p; k <= r; k++)
{
if (L[i] <= R[j]) {
arr[k] = L[i];
i = i + 1;
}
else {
arr[k] = R[j];
j = j + 1;
}
return;
}
}
void mergesort(int* arr, int p, int r) {
if (p < r) {
int q = floor((p + r) / 2);
mergesort(arr, p, q);
mergesort(arr, q + 1, r);
merge(arr, p, q, r);
}
return;
}
int main() {
int r;
cin >> r;
int* arr = new int[r];
for (int i = 0; i < r; i++) {
int num;
cin >> num;
arr[i] = num;
}
int p = 0;
//sortint function
mergesort(arr,p,r);
for (int i = 0; i < r; i++) {
cout << arr[i] << ";";
}
return 0;
}

how to Calculate this series

#include <iostream>
#include <math.h>
using namespace std;
int fact(int number)
{
unsigned long long int p = 1;
if (number == 0) {
return p;
}
for (int i = 1; number >= i; i++) {
p = p * i;
}
return p;
}
int main()
{
long long int a, x, sum = 0, result;
int n ;
cin >> a;
cin >> x;
cin >> n;
for (int k = 0; n >= k; k++) {
result = fact(n) / (fact(k) * fact(n - k));
sum = sum + (result * pow(x, k) * pow(a, n - k));
}
cout << sum;
return 0;
}
I want to calculate this series
So I considered the long long int sum, but the sum number sometimes gets too big. What can I do to save the sum number without using library?
First of all I would suggest to use binomial theorem -- what you are computing is just pow(x+a, n)
If you want to do this through series, do not compute the binomial coefficient using factorials but something like this
int bin_coeff(int n, int k){
int lim = k > n/2 ? k : n - k;
int sum = 1;
for (int i = n; i > lim; i--){
sum *= i;
}
for (int i = 2; i < (n - lim + 1); i++){
sum /= i;
}
return sum;
}

C++ Knapsack Algorithm Implementation

My algorithm for the best-first, branch and bound knapsack problem is giving me a max profit of 80 when it should be 90. I'm wondering where I went wrong... my thinking is the priority queue is a bit off.
Given input:
4,16 // 4 items to follow , 16 capacity knapsack
2,40 // item1.. weighs 2, costs 40
5,30 // item2.. weighs 5, costs 30
10,50 // item3.. weighs 10, costs 50
5,10 // item4.. weighs 5, costs 10
Code:
#include <iostream>
#include <string>
#include <queue>
#include <utility>
typedef struct node{
int level;
int profit;
int weight;
int bound;
} node;
struct node_cmp{
bool operator()(const node& a, const node& b) const{
return a.bound < b.bound;
}
};
int KWF2(int i, int weight, int profit, int *w, int *p, int C, int n){
int weight1 = weight;
int bound = profit;
int j;
float x[n+1];
for(j = i; j <= n; j++){
x[j] = 0;
}
while(weight1 < C && (i <= n)){
if(weight1 + w[i] <= C){
x[i] = 1;
weight1 += w[i];
bound += p[i];
}
else{
x[i] = ((float)C-(float)weight1)/(float)w[i];
weight1 = C;
bound = bound + p[i] * x[i];
}
i++;
}
return bound;
}
void knapsack(int *w, int *p, int C, int maxprofit, int n){
int maxp = maxprofit;
std::priority_queue<node,std::vector<node>,node_cmp> PQ;
node u,v;
v.level = 0;
v.profit = 0;
v.weight = 0;
v.bound = KWF2(v.level+1,v.weight,v.profit,w,p,C,n);
PQ.push(v);
while(!PQ.empty()){
v = PQ.top();
PQ.pop();
if(v.bound > maxp){
u.level = v.level + 1;
//yes child
u.weight = v.weight + w[u.level];
u.profit = v.profit + p[u.level];
if((u.weight <= C) && (u.profit > maxp)){
maxp = u.profit;
}
if(KWF2(u.level+1,u.weight,u.profit,w,p,C,n) > maxp){
PQ.push(u);
}
//no child
u.weight = v.weight;
u.profit = v.profit;
u.bound = KWF2(u.level+1,u.weight,u.profit,w,p,C,n);
if(u.bound > maxp){
PQ.push(u);
}
}
}
printf("%d\n",maxp);
}
int main(int argc, char **argv){
int n,C;
FILE *in = fopen(argv[1],"r");
fscanf(in,"%d,%d",&n,&C);
int w[n+1];
int p[n+1];
float ratio[n+1];
for(int i = 0; i < n; i++){
fscanf(in,"%d,%d",&w[i+1],&p[i+1]);
ratio[i+1] = (float)p[i+1]/(float)w[i+1];
}
int temp_w,temp_p;
float temp_r;
for(int i = 1; i <= n; i++){
for(int j = i + 1; j <= n; j++){
if(ratio[i] < ratio[j]){
temp_w = w[i];
temp_p = p[i];
temp_r = ratio[i];
w[i] = w[j];
p[i] = p[j];
ratio[i] = ratio[j];
w[j] = temp_w;
p[j] = temp_p;
ratio[j] = ratio[i];
}
}
}
int maxprofit = 0;
knapsack(w,p,C,maxprofit,n);
fclose(in);
return 0;
}

mtrix chain multiplication print the sequence of the mattrices

I have written code for matrix chain multiplication in dynamic programming in c++.
there is an error in the recursive call for printing the correct parenthesization of the matrices. I am taking input from text file and giving output on a text file. please help..
#include <iostream>
#include <fstream>
#include <limits.h>
using namespace std;
int * MatrixChainOrder(int p[], int n)
{
static int m[100][100];
static int s[100][100];
int j, q;
int min = INT_MAX;
for (int i = 1; i <= n; i++)
m[i][i] = 0;
for (int L = 2; L <= n; L++) {
for (int i = 1; i <= n - L + 1; i++) {
j = i + L - 1;
m[i][j] = min;
for (int k = i; k <= j - 1; k++) {
q = m[i][k] + m[k + 1][j] + p[i - 1] * p[k] * p[j];
if (q < m[i][j]) {
m[i][j] = q;
s[i][j] = k;
}
}
}
}
return (*s);
}
void Print(int *s, int i, int j)
{
ofstream outfile("output.text");
if (i == j)
{
outfile << "a1";
}
else
outfile << "(";
{
Print(*s, i, s[i][j]);
Print(*s, s[i][j] + 1, j);
outfile << ")";
}
outfile.close();
}
int main()
{
int arr[100];
int num, i = 0;
ifstream infile("input.text");
while (infile)
{
infile >> num;
arr[i] = num;
i++;
}
i = i - 1;
infile.close();
Print(MatrixChainOrder(arr, i - 1), 0, i - 1);
return 0;
}
In C++ it is better to use std::vector for arrays. Aside from that, you can't mix pointers and arrays like that because the compiler loses track of array size.
For example this doesn't work:
int x[10][20];
void foo(int *ptr)
{
//the numbers 10 and 20 have not been passed through
}
But you can change it to
int x[10][20];
void foo(int arr[10][20])
{
//the numbers 10 and 20 are available
}
MatrixChainOrder is supposed to return a number, according to this link
int MatrixChainOrder(int s[100][100], int p[], int n)
{
int m[100][100];
for (int i = 0; i < 100; i++) m[i][i] = 0;
for (int i = 0; i < 100; i++) s[i][i] = 0;
int q = 0;
for (int L = 2; L <= n; L++) {
for (int i = 1; i <= n - L + 1; i++) {
int j = i + L - 1;
m[i][j] = INT_MAX;
for (int k = i; k <= j - 1; k++) {
q = m[i][k] + m[k + 1][j] + p[i - 1] * p[k] * p[j];
if (q < m[i][j]) {
m[i][j] = q;
s[i][j] = k;
}
}
}
}
return q;
}
int main()
{
int arr[] = { 40, 20, 30, 10, 30 };
int array_size = sizeof(arr) / sizeof(int);
int n = array_size - 1;
int s[100][100];
int minimum = MatrixChainOrder(s, arr, n);
printf("{ 40, 20, 30, 10, 30 } should result in 26000 : %d\n", minimum);
return 0;
}
Likewise you can change your Print function
void Print(int s[100][100], int i, int j)
{
if (i < 0 || i >= 100 || j < 0 || j >= 100)
{
cout << "array bound error\n";
}
//safely access s[i][j] ...
}