Decrease the time taken by the code using Dynamic programming












1












$begingroup$


I am trying to solve a question given on Codeforces involving Dynamic Programming with 3D arrays.



Here is my code:



#include<iostream>
#include<vector>
using namespace std;

int mat[403][403][403];
//mat[current_location][final_location][refuel_count_left]
vector<int> city;
int fun(int s,int f, int r){
if(s==f){
return mat[s][f][r] = 0;
}
if(mat[s][f][r]!=0){
return mat[s][f][r];
}
if(s+1==f || r==0){
return mat[s][f][r] = city[f]-city[s];
}

int opt = city[s] + (city[f]-city[s])/(r+1);


int pos = lower_bound(city.begin()+s,city.begin()+f+1,opt) - city.begin();

mat[s][f][r] = max(fun(pos,f,r-1), city[pos] - city[s]);

//cout<<"s=" <<s<<" f="<<f<<" r="<<r<<" mat"<<mat[s][f][r]<<endl;

return mat[s][f][r];
}
int main(){

long long ans=0;
int no_cities,no_vehicle;
cin>>no_cities>>no_vehicle;

city.push_back(0);
for(int i=1;i<=no_cities;++i){
int b;cin>>b;
city.push_back(b);
}
for(int i=0;i<no_vehicle;++i){
int start,finish,costperkm,refuel_count;
cin>>start>>finish>>costperkm>>refuel_count;
long long vol_curr_vehicle = (long long)fun(start,finish,refuel_count)* (long long)costperkm;
//cout<<jj<<" ";
ans = max(ans,vol_curr_vehicle);
}
printf("%lld",ans);
return 0;
}


I've used a 3D array named mat which stores the different DP states.



1st Dimension - index of starting location
2nd Dimension - index of final location to reach
3rd Dimestion - No. of refuelling left



The ith element in the city array represents that the 𝑖-th city is situated at the distance of ai kilometers from the origin.



Explanation for the code :



fun(s,f,r) function takes in 3 arguments representing the current position as s, finish postion as f and refuel_count_left as r.



The problem can be understood as dividing the array city into r+1 segments with the starting index as s and ending index as f.



That is, dividing city[s...f] into r+1 segments. This division should be in such a manner that from all segment max( city[ending index of current segment] - city[starting index of current segment] ) is minimised.



Inside the function fun(s,f,r) which computes and returns mat[s][f][r], the base cases are when :



s==f then return 0; because dividing city[s...f] into r+1 segments is just no segment.



mat[s][f][r]!=0 when mat[s][f][r] has already been computed then return it.



s+1==f || r==0 then return city[f] - city[s]. which mean that either we have no refulling left then we have to reach the final position from the starting position. Or when we are just before the final position then we just directly reach the final postion without refuelling.



If none of the above match then we have to find the position of a element opt which is equal to city[s] + (city[f]-city[s])/(r+1). ie - There will be one segment present to the left opt(a[s...p]) and r segments to the right of opt (a[p....f]).



So, a[s...p] is the first segment out of the r+1 segments and a[p...f] contain the rest r segments out of the r+1 segments



pos is the first position that I've described.



mat[s][f][r] is maximum of fun(pos,f,r-1) and city[pos] - city[s]. where fun(pos,f,r-1) mean that city[s...pos] is the first of the r segments and city[pos...f] are the rest r-1 segments and so now we are going to compute for city[pos...f] with r=r-1 refuellings left.



So, I'm finding the maximum of the difference between the last and first elements of the segments and equating that to mat[s][f][r].



Here is the right answer.



I realized the my code took 1481 ms of time for execution.



What is way that I can use to reduce the time complexity or the time taken by code during execution?










share|improve this question







New contributor




jay is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.







$endgroup$

















    1












    $begingroup$


    I am trying to solve a question given on Codeforces involving Dynamic Programming with 3D arrays.



    Here is my code:



    #include<iostream>
    #include<vector>
    using namespace std;

    int mat[403][403][403];
    //mat[current_location][final_location][refuel_count_left]
    vector<int> city;
    int fun(int s,int f, int r){
    if(s==f){
    return mat[s][f][r] = 0;
    }
    if(mat[s][f][r]!=0){
    return mat[s][f][r];
    }
    if(s+1==f || r==0){
    return mat[s][f][r] = city[f]-city[s];
    }

    int opt = city[s] + (city[f]-city[s])/(r+1);


    int pos = lower_bound(city.begin()+s,city.begin()+f+1,opt) - city.begin();

    mat[s][f][r] = max(fun(pos,f,r-1), city[pos] - city[s]);

    //cout<<"s=" <<s<<" f="<<f<<" r="<<r<<" mat"<<mat[s][f][r]<<endl;

    return mat[s][f][r];
    }
    int main(){

    long long ans=0;
    int no_cities,no_vehicle;
    cin>>no_cities>>no_vehicle;

    city.push_back(0);
    for(int i=1;i<=no_cities;++i){
    int b;cin>>b;
    city.push_back(b);
    }
    for(int i=0;i<no_vehicle;++i){
    int start,finish,costperkm,refuel_count;
    cin>>start>>finish>>costperkm>>refuel_count;
    long long vol_curr_vehicle = (long long)fun(start,finish,refuel_count)* (long long)costperkm;
    //cout<<jj<<" ";
    ans = max(ans,vol_curr_vehicle);
    }
    printf("%lld",ans);
    return 0;
    }


    I've used a 3D array named mat which stores the different DP states.



    1st Dimension - index of starting location
    2nd Dimension - index of final location to reach
    3rd Dimestion - No. of refuelling left



    The ith element in the city array represents that the 𝑖-th city is situated at the distance of ai kilometers from the origin.



    Explanation for the code :



    fun(s,f,r) function takes in 3 arguments representing the current position as s, finish postion as f and refuel_count_left as r.



    The problem can be understood as dividing the array city into r+1 segments with the starting index as s and ending index as f.



    That is, dividing city[s...f] into r+1 segments. This division should be in such a manner that from all segment max( city[ending index of current segment] - city[starting index of current segment] ) is minimised.



    Inside the function fun(s,f,r) which computes and returns mat[s][f][r], the base cases are when :



    s==f then return 0; because dividing city[s...f] into r+1 segments is just no segment.



    mat[s][f][r]!=0 when mat[s][f][r] has already been computed then return it.



    s+1==f || r==0 then return city[f] - city[s]. which mean that either we have no refulling left then we have to reach the final position from the starting position. Or when we are just before the final position then we just directly reach the final postion without refuelling.



    If none of the above match then we have to find the position of a element opt which is equal to city[s] + (city[f]-city[s])/(r+1). ie - There will be one segment present to the left opt(a[s...p]) and r segments to the right of opt (a[p....f]).



    So, a[s...p] is the first segment out of the r+1 segments and a[p...f] contain the rest r segments out of the r+1 segments



    pos is the first position that I've described.



    mat[s][f][r] is maximum of fun(pos,f,r-1) and city[pos] - city[s]. where fun(pos,f,r-1) mean that city[s...pos] is the first of the r segments and city[pos...f] are the rest r-1 segments and so now we are going to compute for city[pos...f] with r=r-1 refuellings left.



    So, I'm finding the maximum of the difference between the last and first elements of the segments and equating that to mat[s][f][r].



    Here is the right answer.



    I realized the my code took 1481 ms of time for execution.



    What is way that I can use to reduce the time complexity or the time taken by code during execution?










    share|improve this question







    New contributor




    jay is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.







    $endgroup$















      1












      1








      1





      $begingroup$


      I am trying to solve a question given on Codeforces involving Dynamic Programming with 3D arrays.



      Here is my code:



      #include<iostream>
      #include<vector>
      using namespace std;

      int mat[403][403][403];
      //mat[current_location][final_location][refuel_count_left]
      vector<int> city;
      int fun(int s,int f, int r){
      if(s==f){
      return mat[s][f][r] = 0;
      }
      if(mat[s][f][r]!=0){
      return mat[s][f][r];
      }
      if(s+1==f || r==0){
      return mat[s][f][r] = city[f]-city[s];
      }

      int opt = city[s] + (city[f]-city[s])/(r+1);


      int pos = lower_bound(city.begin()+s,city.begin()+f+1,opt) - city.begin();

      mat[s][f][r] = max(fun(pos,f,r-1), city[pos] - city[s]);

      //cout<<"s=" <<s<<" f="<<f<<" r="<<r<<" mat"<<mat[s][f][r]<<endl;

      return mat[s][f][r];
      }
      int main(){

      long long ans=0;
      int no_cities,no_vehicle;
      cin>>no_cities>>no_vehicle;

      city.push_back(0);
      for(int i=1;i<=no_cities;++i){
      int b;cin>>b;
      city.push_back(b);
      }
      for(int i=0;i<no_vehicle;++i){
      int start,finish,costperkm,refuel_count;
      cin>>start>>finish>>costperkm>>refuel_count;
      long long vol_curr_vehicle = (long long)fun(start,finish,refuel_count)* (long long)costperkm;
      //cout<<jj<<" ";
      ans = max(ans,vol_curr_vehicle);
      }
      printf("%lld",ans);
      return 0;
      }


      I've used a 3D array named mat which stores the different DP states.



      1st Dimension - index of starting location
      2nd Dimension - index of final location to reach
      3rd Dimestion - No. of refuelling left



      The ith element in the city array represents that the 𝑖-th city is situated at the distance of ai kilometers from the origin.



      Explanation for the code :



      fun(s,f,r) function takes in 3 arguments representing the current position as s, finish postion as f and refuel_count_left as r.



      The problem can be understood as dividing the array city into r+1 segments with the starting index as s and ending index as f.



      That is, dividing city[s...f] into r+1 segments. This division should be in such a manner that from all segment max( city[ending index of current segment] - city[starting index of current segment] ) is minimised.



      Inside the function fun(s,f,r) which computes and returns mat[s][f][r], the base cases are when :



      s==f then return 0; because dividing city[s...f] into r+1 segments is just no segment.



      mat[s][f][r]!=0 when mat[s][f][r] has already been computed then return it.



      s+1==f || r==0 then return city[f] - city[s]. which mean that either we have no refulling left then we have to reach the final position from the starting position. Or when we are just before the final position then we just directly reach the final postion without refuelling.



      If none of the above match then we have to find the position of a element opt which is equal to city[s] + (city[f]-city[s])/(r+1). ie - There will be one segment present to the left opt(a[s...p]) and r segments to the right of opt (a[p....f]).



      So, a[s...p] is the first segment out of the r+1 segments and a[p...f] contain the rest r segments out of the r+1 segments



      pos is the first position that I've described.



      mat[s][f][r] is maximum of fun(pos,f,r-1) and city[pos] - city[s]. where fun(pos,f,r-1) mean that city[s...pos] is the first of the r segments and city[pos...f] are the rest r-1 segments and so now we are going to compute for city[pos...f] with r=r-1 refuellings left.



      So, I'm finding the maximum of the difference between the last and first elements of the segments and equating that to mat[s][f][r].



      Here is the right answer.



      I realized the my code took 1481 ms of time for execution.



      What is way that I can use to reduce the time complexity or the time taken by code during execution?










      share|improve this question







      New contributor




      jay is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.







      $endgroup$




      I am trying to solve a question given on Codeforces involving Dynamic Programming with 3D arrays.



      Here is my code:



      #include<iostream>
      #include<vector>
      using namespace std;

      int mat[403][403][403];
      //mat[current_location][final_location][refuel_count_left]
      vector<int> city;
      int fun(int s,int f, int r){
      if(s==f){
      return mat[s][f][r] = 0;
      }
      if(mat[s][f][r]!=0){
      return mat[s][f][r];
      }
      if(s+1==f || r==0){
      return mat[s][f][r] = city[f]-city[s];
      }

      int opt = city[s] + (city[f]-city[s])/(r+1);


      int pos = lower_bound(city.begin()+s,city.begin()+f+1,opt) - city.begin();

      mat[s][f][r] = max(fun(pos,f,r-1), city[pos] - city[s]);

      //cout<<"s=" <<s<<" f="<<f<<" r="<<r<<" mat"<<mat[s][f][r]<<endl;

      return mat[s][f][r];
      }
      int main(){

      long long ans=0;
      int no_cities,no_vehicle;
      cin>>no_cities>>no_vehicle;

      city.push_back(0);
      for(int i=1;i<=no_cities;++i){
      int b;cin>>b;
      city.push_back(b);
      }
      for(int i=0;i<no_vehicle;++i){
      int start,finish,costperkm,refuel_count;
      cin>>start>>finish>>costperkm>>refuel_count;
      long long vol_curr_vehicle = (long long)fun(start,finish,refuel_count)* (long long)costperkm;
      //cout<<jj<<" ";
      ans = max(ans,vol_curr_vehicle);
      }
      printf("%lld",ans);
      return 0;
      }


      I've used a 3D array named mat which stores the different DP states.



      1st Dimension - index of starting location
      2nd Dimension - index of final location to reach
      3rd Dimestion - No. of refuelling left



      The ith element in the city array represents that the 𝑖-th city is situated at the distance of ai kilometers from the origin.



      Explanation for the code :



      fun(s,f,r) function takes in 3 arguments representing the current position as s, finish postion as f and refuel_count_left as r.



      The problem can be understood as dividing the array city into r+1 segments with the starting index as s and ending index as f.



      That is, dividing city[s...f] into r+1 segments. This division should be in such a manner that from all segment max( city[ending index of current segment] - city[starting index of current segment] ) is minimised.



      Inside the function fun(s,f,r) which computes and returns mat[s][f][r], the base cases are when :



      s==f then return 0; because dividing city[s...f] into r+1 segments is just no segment.



      mat[s][f][r]!=0 when mat[s][f][r] has already been computed then return it.



      s+1==f || r==0 then return city[f] - city[s]. which mean that either we have no refulling left then we have to reach the final position from the starting position. Or when we are just before the final position then we just directly reach the final postion without refuelling.



      If none of the above match then we have to find the position of a element opt which is equal to city[s] + (city[f]-city[s])/(r+1). ie - There will be one segment present to the left opt(a[s...p]) and r segments to the right of opt (a[p....f]).



      So, a[s...p] is the first segment out of the r+1 segments and a[p...f] contain the rest r segments out of the r+1 segments



      pos is the first position that I've described.



      mat[s][f][r] is maximum of fun(pos,f,r-1) and city[pos] - city[s]. where fun(pos,f,r-1) mean that city[s...pos] is the first of the r segments and city[pos...f] are the rest r-1 segments and so now we are going to compute for city[pos...f] with r=r-1 refuellings left.



      So, I'm finding the maximum of the difference between the last and first elements of the segments and equating that to mat[s][f][r].



      Here is the right answer.



      I realized the my code took 1481 ms of time for execution.



      What is way that I can use to reduce the time complexity or the time taken by code during execution?







      c++ algorithm time-limit-exceeded dynamic-programming






      share|improve this question







      New contributor




      jay is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.











      share|improve this question







      New contributor




      jay is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.









      share|improve this question




      share|improve this question






      New contributor




      jay is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.









      asked 11 mins ago









      jayjay

      1062




      1062




      New contributor




      jay is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.





      New contributor





      jay is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.






      jay is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.






















          0






          active

          oldest

          votes











          Your Answer





          StackExchange.ifUsing("editor", function () {
          return StackExchange.using("mathjaxEditing", function () {
          StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
          StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
          });
          });
          }, "mathjax-editing");

          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "196"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: false,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });






          jay is a new contributor. Be nice, and check out our Code of Conduct.










          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f213557%2fdecrease-the-time-taken-by-the-code-using-dynamic-programming%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          0






          active

          oldest

          votes








          0






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          jay is a new contributor. Be nice, and check out our Code of Conduct.










          draft saved

          draft discarded


















          jay is a new contributor. Be nice, and check out our Code of Conduct.













          jay is a new contributor. Be nice, and check out our Code of Conduct.












          jay is a new contributor. Be nice, and check out our Code of Conduct.
















          Thanks for contributing an answer to Code Review Stack Exchange!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          Use MathJax to format equations. MathJax reference.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f213557%2fdecrease-the-time-taken-by-the-code-using-dynamic-programming%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Список кардиналов, возведённых папой римским Каликстом III

          Deduzione

          Mysql.sock missing - “Can't connect to local MySQL server through socket”