-2

This has a time limit of one second. My program takes 1.01s for some unknown test cases. The problem is

You are developing a smartphone app. You have a list of potential customers for your app. Each customer has a budget and will buy the app at your declared price if and only if the price is less than or equal to the customer's budget.

You want to fix a price so that the revenue you earn from the app is maximized. Find this maximum possible revenue.

For instance, suppose you have 4 potential customers and their budgets are 30, 20, 53 and 14. In this case, the maximum revenue you can get is 60.

I'm sure that the code is correct. I just want to optimize it. Please help me do so. I'm a beginner.

Code:

#include <iostream>
#include <vector>
#include <numeric>
#include <algorithm>

using namespace std;

int main()
{
    ios::sync_with_stdio(false);
    int n, x, i, j, k;
    cin >> n;
    vector<int> v;
    for (i = 0; i < n; ++i) 
    {
        cin >> x;
        v.push_back(x);
    }
    int maximum = *max_element(v.begin(), v.end());
    int minimum = *min_element(v.begin(), v.end());
    vector<long long int> sums;
    for (j = minimum; j <= maximum; ++j)
    {
        vector<int> prices;
        for (k = 0; k < n; ++k)
        {
            if (j > v[k]) {
                ;
            } else {
                prices.push_back(j);
            }
        }
        sums.push_back(accumulate(prices.begin(), prices.end(), 0));
        prices.clear();
    }
    long long int maxsum = *max_element(sums.begin(), sums.end());
    cout << maxsum;
}
Nishchay
  • 41
  • 6
  • First thing when talking about optimization: Did you actually _meassure_ a bottleneck or other performance issue? Can you objectively say, that this code _needs_ optimization? But there is actually another forum that would be more fitting for this kind of question: https://codereview.stackexchange.com/ – Lukas-T Feb 20 '20 at 17:48
  • Can you update max and min as you read in the values? That prevents the two O(n) computations – Michael Bianconi Feb 20 '20 at 17:48
  • This will probably work in one second. But have you considered that you don't really need `prices` *or* `sums`? – user253751 Feb 20 '20 at 17:50
  • I would try resizing the vector and doing index assignment in the beginning. The price vector looks like it can be declared with the correct size. And I agree that tracking min and max while taking the input would be better. – sweenish Feb 20 '20 at 17:50
  • a good way to see how "optimal" some code is, is to either show it to some one else, if they can understand it, the code cannot be too bad. Alternatively dont look at it for a week, if yourself can still understand it after week, the code cannot be too bad. The attribute "optimal" for code is much more about readability and simplicity than anything else – 463035818_is_not_an_ai Feb 20 '20 at 17:50
  • You can do min and max together in less time (typically) than doing them individually. http://www.cplusplus.com/reference/algorithm/minmax_element/ – L. Scott Johnson Feb 20 '20 at 17:51
  • @churill I'll see the forum. I submitted my solution and got a TLE. So it DOES need optimization. – Nishchay Feb 20 '20 at 17:51
  • 2
    I would think this is solvable in `O(NlogN)`. If you sort, then you can just take the first element times the size of the vector and compare that to the second element times the size of the vector minus one. If that's better, repeat moving the indices and amounts to multiply by accordingly. – NathanOliver Feb 20 '20 at 17:58
  • Looking further, nested fors? And that if/else block is terrible. If one branch won't do anything, just re-write your condition. An explicitly empty branch is pointless. – sweenish Feb 20 '20 at 17:58
  • @user253751 I need them. – Nishchay Feb 20 '20 at 17:58
  • And here's the link to the exercise so people can experiment in the same playground: https://www.codechef.com/ZCOPRAC/problems/ZCO14003 – sweenish Feb 20 '20 at 17:58
  • @MichaelBianconi How do I do that? – Nishchay Feb 20 '20 at 17:59
  • @Nishchay manually check x as it's read – Michael Bianconi Feb 20 '20 at 18:00
  • @sweenish how do I do that? – Nishchay Feb 20 '20 at 18:03
  • @Nishchay No, you don't need them. You only need `sum` and `maxsum`. – user253751 Feb 20 '20 at 18:05
  • 2
    Optimizing the algorithm is usually usefull. For example you only need to test the exact prices that the people can pay. For example all but one can pay 15 and all but one can pay 20, you only need to test 14, then 20, then 30 and so on. To point you in the direction that Nathan proposed. – Lukas-T Feb 20 '20 at 18:13
  • What resource are you using to learn this topic? Which book on algorithm design? – Asteroids With Wings Feb 20 '20 at 18:24
  • @churill Thanks. It seemed to work in the sample test cases but it wasn't accepted officially. The output was incorrect. Here is the code: – Nishchay Feb 20 '20 at 18:42
  • `#include #include #include #include using namespace std; int main() { ios::sync_with_stdio(false); int n, x, i, j; cin >> n; vector v; for (i = 0; i < n; ++i) { cin >> x; v.push_back(x); } sort(v.begin(), v.end()); vector store; for (j = 0; j < n; ++j) { store.push_back(v[j]*(n-j)); } sort(store.begin(), store.end()); cout << store[n-1]; }` – Nishchay Feb 20 '20 at 18:43

1 Answers1

2

Here's an example that CodeChef timed at 0.19 s.

#include <algorithm>
#include <iostream>
#include <vector>

int main() {
  int number;
  std::vector<int> budgets;

  std::cin >> number;

  budgets.resize(number);

  for (std::size_t i = 0; i < budgets.size(); ++i) {
    std::cin >> budgets[i];
  }

  std::sort(budgets.begin(), budgets.end());

  std::size_t max = 0;
  for (std::size_t i = 0; i < budgets.size(); ++i) {
    std::size_t tmp = budgets[i] * (budgets.size() - i);
    if (tmp > max) {
      max = tmp;
    }
  }

  std::cout << max;
}

Once I know the size needed for the vector, I resize it. This stops the vector resizing at element 2, 4, 8, etc. One resize is faster than >1. Now, because it's been resized, I can also just use direct element access with []. .at() is safer but brings exceptions into play, and this exercise is about minimizing runtime, so we won't do it.

The key here is sorting the vector. It's explained in a comment, but the general idea is that sorted data is much faster to work with than un-sorted data. The sort itself runs in O(nlogn) time, but we now get a much faster algorithm.

The new algorithm is relying on sorted data. Index 0 holds the smallest price, which means everyone could afford it at that price. My revenue would be element 0's budget times the number of elements (.size()). When I get to the second element, everyone except index zero can afford it, so my revenue is element 1's budget times the size minus one. And so on. As I calculate these potential revenues, I compare them against my max variable. If I calculate bigger, I replace max with the new value, otherwise I leave it alone.

You'll note that I don't know what price to actually set it at. It wasn't a requirement of the submission, so I don't care.

Personal opinion time, sites like this are terrible for learning. You're better off finding a youtube series or taking a course or getting a good book. These sorts of code golf exercises can be fun, but they do nothing to teach best practices or even what you're doing. They're usually just a test of pattern-finding (which can be beneficial) and rote memorization of certain algorithms (less great).

sweenish
  • 4,793
  • 3
  • 12
  • 23
  • `#include #include #include #include using namespace std; int main() { ios::sync_with_stdio(false); int n, x, i, j; cin >> n; vector v; for (i = 0; i < n; ++i) { cin >> x; v.push_back(x); } sort(v.begin(), v.end()); vector store; for (j = 0; j < n; ++j) { store.push_back(v[j]*(n-j)); } sort(store.begin(), store.end()); cout << store[n-1]; }`It shows that it's incorrect. What did I mess up? – Nishchay Feb 20 '20 at 18:54
  • I don't see an immediate error, but I have to wonder why you insist on storing all revenue values, or why you think the line `ios::sync_with_stdio(false);` is needed. Or why you forward declare your loop counter variables. You are still allowing the vectors to resize themselves multiple times. There's a lot that I would consider "not right" with your code. This leads to the other problem with sites like this. They don't tell you what problem set failed. It makes investigating a lot harder. Otherwise this is a prime example of why knowing how to use a debugger is so important. – sweenish Feb 20 '20 at 20:30