|
| 1 | +/* |
| 2 | + PROBLEM |
| 3 | + Bag of Tokens |
| 4 | + |
| 5 | + You start with an initial power of power, an initial score of 0, and a bag of tokens given as an integer array tokens, where each tokens[i] denotes the value of tokeni. |
| 6 | +
|
| 7 | + Your goal is to maximize the total score by strategically playing these tokens. In one move, you can play an unplayed token in one of the two ways (but not both for the same token): |
| 8 | +
|
| 9 | + Face-up: If your current power is at least tokens[i], you may play tokeni, losing tokens[i] power and gaining 1 score. |
| 10 | + Face-down: If your current score is at least 1, you may play tokeni, gaining tokens[i] power and losing 1 score. |
| 11 | + Return the maximum possible score you can achieve after playing any number of tokens. |
| 12 | +
|
| 13 | + LeetCode: https://leetcode.com/problems/bag-of-tokens/ |
| 14 | +*/ |
| 15 | + |
| 16 | +#include <iostream> |
| 17 | +#include <vector> |
| 18 | +#include <algorithm> |
| 19 | +using namespace std; |
| 20 | + |
| 21 | +class Solution { |
| 22 | +public: |
| 23 | + int bagOfTokensScore(vector<int>& tokens, int power) { |
| 24 | + // Handle edge case of single token |
| 25 | + if (tokens.size() == 1) { |
| 26 | + return tokens[0] <= power; // Can only play face-up if power is sufficient |
| 27 | + } |
| 28 | + |
| 29 | + // Sort tokens to optimize power-score trade-offs |
| 30 | + // Smallest tokens first for face-up plays |
| 31 | + // Largest tokens last for face-down plays |
| 32 | + sort(tokens.begin(), tokens.end()); |
| 33 | + |
| 34 | + int score = 0; // Current score |
| 35 | + int ans = 0; // Maximum score achieved |
| 36 | + int i = 0; // Left pointer for face-up plays (smallest tokens) |
| 37 | + int j = tokens.size() - 1; // Right pointer for face-down plays (largest tokens) |
| 38 | + |
| 39 | + while (i < j) { |
| 40 | + // Play face-up while we have enough power |
| 41 | + // Use smallest tokens to maximize remaining power |
| 42 | + while (i < j && tokens[i] <= power) { |
| 43 | + power -= tokens[i++]; // Lose token[i] power |
| 44 | + score++; // Gain 1 score |
| 45 | + ans = max(ans, score); // Update maximum score |
| 46 | + } |
| 47 | + |
| 48 | + // If we have score to spend, trade it for power |
| 49 | + // Use largest tokens to maximize gained power |
| 50 | + if (score > 0) { |
| 51 | + score--; // Lose 1 score |
| 52 | + power += tokens[j--]; // Gain token[j] power |
| 53 | + } else { |
| 54 | + // If no score to trade and not enough power |
| 55 | + // for next token, we're done |
| 56 | + break; |
| 57 | + } |
| 58 | + } |
| 59 | + |
| 60 | + // Handle last token if still have enough power |
| 61 | + if (i <= j && tokens[i] <= power) { |
| 62 | + ans = max(ans, score + 1); |
| 63 | + } |
| 64 | + |
| 65 | + return ans; |
| 66 | + } |
| 67 | +}; |
| 68 | + |
| 69 | +int main() { |
| 70 | + // Test cases |
| 71 | + vector<pair<vector<int>, int>> testCases = { |
| 72 | + // Format: {tokens array, initial power} |
| 73 | + {{100}, 50}, // Single token case |
| 74 | + {{100,200,300,400}, 200}, // Example 1 |
| 75 | + {{200,100}, 150}, // Example 2 |
| 76 | + {{100,200,300,400}, 50}, // Low initial power |
| 77 | + {{}, 100}, // Empty tokens array |
| 78 | + {{100,200,300,400}, 1000}, // High initial power |
| 79 | + {{50,100,150,200}, 150} // Multiple possible trades |
| 80 | + }; |
| 81 | + |
| 82 | + Solution solution; |
| 83 | + |
| 84 | + // Process each test case |
| 85 | + for (int i = 0; i < testCases.size(); i++) { |
| 86 | + cout << "\nTest Case " << i + 1 << ":\n"; |
| 87 | + |
| 88 | + // Print input |
| 89 | + cout << "Initial Power: " << testCases[i].second << "\n"; |
| 90 | + cout << "Tokens: "; |
| 91 | + for (int token : testCases[i].first) { |
| 92 | + cout << token << " "; |
| 93 | + } |
| 94 | + cout << "\n"; |
| 95 | + |
| 96 | + // Calculate and print result |
| 97 | + int maxScore = solution.bagOfTokensScore(testCases[i].first, testCases[i].second); |
| 98 | + cout << "Maximum Possible Score: " << maxScore << "\n"; |
| 99 | + |
| 100 | + // Print explanation for better understanding |
| 101 | + cout << "Explanation: "; |
| 102 | + if (testCases[i].first.empty()) { |
| 103 | + cout << "Empty token array, no plays possible.\n"; |
| 104 | + } else if (testCases[i].first.size() == 1) { |
| 105 | + cout << "Single token case - can only play face-up if power is sufficient.\n"; |
| 106 | + } else { |
| 107 | + cout << "Can play tokens optimally by using smallest tokens face-up " |
| 108 | + << "and largest tokens face-down.\n"; |
| 109 | + } |
| 110 | + } |
| 111 | + |
| 112 | + return 0; |
| 113 | +} |
0 commit comments