Distributing resources for maximum gain
This is a knapsack problem. In the most basic version, you have a single resource (e.g., space in your knapsack) and you're trying to choose which items to put in it so you can carry the greatest value. People have also studied multi-constraint knapsack problems, which is the variant you're directly asking about.

The bad news is that knapsack problems are, in general, NP-complete. The good news is that they can be solved in pseudopolynomial1 time using dynamic programming, which is often practical.  They can also be approximated fairly well: for any fixed&nbsp;$\varepsilon$, there is a polynomial time algorithm that will give you the answer to within a factor of $1\pm\varepsilon$. However, the dependence on the running time is superpolynomial, unless P$\,=\,$NP.



1 Pseudopolynomial time means that the running time is a polynomial function of the numbers represented in the input, whereas polynomial time means the running time is a polynomial function of the size of the input in bits. For example, the algorithm read n; for i=1 to n do print "hello"; end is pseudopolynomial: if its input is&nbsp;$n$, it performs $n$&nbsp;iterations but, if the input is written as a $b$-bit binary number, then $n$&nbsp;could be as big as&nbsp;$2^b$, so the algorithm isn't truly polynomial.