How to apply convex hull optimization in dynamic programming? - optimization

I am trying to solve this problem on codeforces using dynamic programming. I have made the recurrence which is of O(N^2) complexity but it is timing out. I know that the complexity of this solution can be reduced to O(N) via Convex hull optimization which is explained here. But I am not able to reduce the complexity. Please help.
This is my code.
#include <bits/stdc++.h>
using namespace std;
#define MAX 100005
typedef long long ll;
ll a[MAX],b[MAX],dp[MAX];
int main()
{
int n;
cin >> n;
for(int i = 0; i < n; i++)
cin >> a[i];
for(int i = 0; i < n; i++)
cin >> b[i];
dp[0] = 0;
for(int i = 1; i < n; i++)
{
dp[i] = 1e18;
for(int j = 0; j < i; j++)
{
dp[i] = min(dp[i],dp[j] + a[i] * b[j]);
}
}
cout << dp[n-1];
}

Related

what is the time complexity of following C++ code?

int sum = 0, j;
for (j=0; j < N; j++)
for (j=0; j < 100; j++)
sum = sum +j;
I want to know how we can solve it, meaning how to find the time complexity of this code?

stringstream segmentation fault

Using linux and g++.
This works:
stringstream ss;
for (int k = 1; k < 1000; k++){
}
This should also works but result in "segmentation fault":
for (int k = 1; k <1000; k++){
stringstream ss;
}
Why?
Thank you Antonio Perez for your reply.
Actually my code was exactly this:
#pragma pack(1)
#include <sstream>
#include <iostream>
int main(){
for (int i = 0; i < 2; i++){
std::stringstream ss;
}
}
Amazingly if I displace the #pragma pack(1) like this:
#include <sstream>
#pragma pack(1)
#include <iostream>
int main(){
for (int i = 0; i < 2; i++){
std::stringstream ss;
}
}
...then no error occurs!
Is there a possible (non-bug) reason for why sstream does not permit packing of its structure?

multidimensional very large array

Hi i want to use multidimensional very large array. I tried following code. It compiles but when i execute it it gives me segmentation fault error.
'int NT = 35; int NX = 25; int NY = 25; int NZ = 25;
double dt = 0.1; double dx = 0.5; double dy = 0.5; double dz = 0.5;
double PosT[NT];
double PosX[NX]; double PosY[NY]; double PosZ[NZ];
for(int i=0;i<NT;i++)
PosT[i] = i*dt+dt;
for(int i=0; i<NX;i++)
PosX[i] = dx*i;
for(int i=0; i<NY;i++)
PosY[i] = dy*i;
for(int i=0; i<NZ;i++)
PosZ[i] = dz*i;
double* b_x=(double*)malloc(NX*NY*NZ*sizeof(double));
double* b_y=(double*)malloc(NX*NY*NZ*sizeof(double));
double** B=(double**)malloc(NX*NY*NZ*NT*sizeof(double*));
if(b_x==NULL||b_y==NULL){
cout<<"Malloc space error!"<<endl;
return 0;
}
for(int ix=0;ix<NX;ix++){
for(int iy=0;iy<NY;iy++){
for(int iz=0;iz<NZ;iz++){
int position=ix*NY*NZ+iy*NZ+iz;
b_x[position] =0.;
b_y[position] =0.;
}
}
}'
but when i work in below part then i got segmentation error, my codes next part is following lines which include 2d arrays. and this 2d array is very large ,
perhaps due to this i am getting segmentation error
'if(B==NULL){
cout<<"Malloc space error!"<<endl;
return 0;
}
cout<<"work"<<endl;
for(int ix=0;ix<NX;ix++){
for(int iy=0;iy<NY;iy++){
for(int iz=0;iz<NZ;iz++){
int position=ix*NY*NZ+iy*NZ+iz;
for(int it=0;it<NT;it++){
B[position][it]=0.;
}
}
}
}
cout<<"not working"<<endl;'
so code between work and not working has problem which causes segmentation error. Any solutions for this.
int NT = 35; int NX = 25; int NY = 25; int NZ = 25;
For simplicity, let's change all of these to NT=NX=NY=NZ=2. This line:
double** B=(double**)malloc(NX*NY*NZ*NT*sizeof(double*));
would then allocate space for 16 pointers. On the first iteration through the loops, this line:
B[position][it]=0.;
would be equivalent to:
double *tmp = B[0]; // Load uninitialized pointer from B[0]
tmp[0] = 0.0; // Dereference uninitialized pointer to store something.
It shouldn't be at all surprising that this code results in a SIGSEGV.
What you probably meant:
double *B = malloc(NX*NY*NZ*NT*sizeof(double));
for(int ix = 0; ix < NX; ix++) {
for(int iy = 0; iy < NY; iy++) {
for(int iz = 0; iz < NZ; iz++) {
for(int it = 0; it < NT; it++) {
int position = NT * (NZ * (NY * ix + iy) + iz) + it;
B[position] = 0.0;
}
}
}
}

Time complexity verification

So I have this block of code:
int sum=0;
for (int i=1; i<n; ++i){
for (int j=1; j<i*i; ++j){
if (j%i==0){
for (int k=0; k<j; ++k){
++sum;
}
}
}
}
and I figured this has a $O(n^5)$ complexity. I tried timing this to verify it but I couldn't tell if the best fit was of $n^4$ or $n^5$.
The complexity is n^4.
The reason is that the third for will run O(n^2) times instead of O(n^3) as you may have calculated. The if case will only be called (i*i)^(1/2) = O(n) times for each step of the outer for, because the number of multiples of i from 1 to i*i is exactly i = O(n).
So I have this block of code:
int sum=0;
for (int i=1; i<n; ++i){
for (int j=1; j<i*i; ++j){ // O(n)
if (j%i==0){
for (int k=0; k<j; ++k){ // O(n^2)
++sum; // O(n^4)
}
}
}
}

C logic error in for statement with break

Am running this C program, but instead of answering "The answer is 10", it sends back the message: "The answer is 0", even though it breaks at the right time.
Can you tell me what's wrong?
#import <Foundation/Foundation.h>
int main (int argc, const char * argv[])
{
int i;
for(int i = 0; i < 12; i++){
printf("Checking i = %d\n", i);
if(i + 90 == i * i) {
break;
}
}
printf("The answer is %d.\n", i);
}
The problem is you have two i's.
int main (int argc, const char * argv[])
{
int i; //Declares outer i
for(int i = 0; i < 12; i++) //Declares a NEW i
{
printf("Checking i = %d\n", i);
if(i + 90 == i * i)
{
break;
}
}
printf("The answer is %d.\n", i); //Uses the outer i
}
Basic scope confusion: You have two different variables called i: One in the outer scope of the main function body, and another, overriding one inside the for loop.
The outer variable is uninitialized, so in fact you have undefined behaviour.
What you mean to say is this:
int i;
for (i = 0; i < 12; i++)
/* ^^^^^ use existing variable! */
{
printf("Checking i = %d\n", i);
if (i + 90 == i * i)
{
break;
}
}
Could it be the extra "int"? You're declaring another instance of "i" in the for loop that goes out of scope when the loop exits.
for(int i = 0; i < 12; i++){
You're creating another i here, which hides the i outside the scope of the for loop.
Change to:
int i;
...
for (i = 0; i < 12; i++){
Because you've got two DIFFERENT variables "i" - the one in the inner scope (which you increment from 0..11), and the one in the outer scope. You print the one in the outer scope.
SOLUTION:
change "for (int i=...)" to "for (i=...)"