Let d_i be the download and installation size of app i and s_i be size of app i after installation. We can assume that d_i >= s_i for all i, as that assumption doesn't change the validity of any installation.

Note: Perhaps this assumption should just be guaranteed by the problem statement.

Lemma: Suppose apps a_1, ..., a_k are sorted by the value of (s_i - d_i) in ascending order. If we cannot install the apps in the order 1, 2, ..., k, then we cannot install them in any other order.

Proof: Suppose the apps are installed in an order where (s_i - d_i) is not ascending. Then there exists a pair of apps u, v, where v is installed right after u and (s_u - d_u) > (s_v - d_v).

Because we were able to install the two apps, we know that the following statements are true:
(c is capacity of the phone, S is size occupied before the installation of u)
* S + max(s_u, d_u) = S + d_u <= c
* S + s_u + max(s_v, d_v) = S + s_u + d_v <= c

If we kept the same installation order except swapping u and v, we'd need these inequalities to be true:
* S + d_v <= c
* S + s_v + d_u <= c

Since in the previous order we had S + s_u + d_v <= c, we have S + d_v <= c in the new order. Finally, since (s_u - d_u) > (s_v - d_v), we have
S + (s_u - d_u) > S + (s_v - d_v)
S + s_u + d_v > S + s_v + d_u

In the previous order we had c >= S + s_u + d_v, which implies c >= S + s_v + d_u.

Hence swapping the order of u and v is valid. QED.


Since the ordering used in the lemma is total, we know that the app with the lowest value of (s_i - d_i) is either installed first or not installed at all. The second lowest app is installed first or second, but second only if the lowest app is installed. And so on.

The algorithm: Sort all apps by the value of (s_i - d_i) and iterate through them. Try to solve a knapsack problem of capacity c: calculate dp[s][a] (for s up to c, a up to n), the largest number of apps from the first 'a' apps that can be installed occupying 's' megabytes after installation.

We don't need to store a 2D table and can actually do the updates in an array dp[0..c].


Difficulty: 60%
