URL: http://www.topcoder.com/stat?c=problem_statement&pm=11019
class KiwiJuice { public: int theProfit(int, vector <int>, vector <int>); }; int dp[51][1<<16]; vector<int> data; vector<int> price; int _C; // f(current volume of the special bottle, bitmask of the used bottles) int f(int i, int mask) { // caching mechanism if (dp[i][mask] != -1) return dp[i][mask]; // base case if (mask+1 == (1 << (data.size()))-1) { return price[i]; } int res = 0; for (int j = 1; j < data.size(); j++) { if (mask & (1 << j)) continue; // already used // the next bottle to process int next = data[j]; int d1 = 0; if (i + next >= _C) { // one of the bottles is full, the other is i+next-_C volume d1 = price[_C] + f(i+next-_C, mask | (1 << j)); } else { // change to i + next (and used up the empty for bottle[j]) d1 = price[0] + f(i+next, mask | (1 << j)); } // don't add more to our current bottle // we swap with bottle j and "use" up our bottle int d2 = f(next, mask | (1 << j)) + price[i]; // take the maximum of the decision branches res >?= max(d1,d2); } return dp[i][mask] = res; } int KiwiJuice::theProfit(int C, vector <int> bottles, vector <int> prices) { price = prices; int res = 0; _C = C; memset(dp,-1,sizeof(dp)); data = bottles; return res = f(data[0],0); // arbitrarily assign bottle 0 to be our special bottle }