1 题目
You have an initial power P
, an initial score of 0
points, and a bag of tokens.
Each token can be used at most once, has a value token[i]
, and has potentially two ways to use it.
- If we have at least
token[i]
power, we may play the token face up, losingtoken[i]
power, and gaining1
point. - If we have at least
1
point, we may play the token face down, gainingtoken[i]
power, and losing1
point.
Return the largest number of points we can have after playing any number of tokens.
Example 1:
Input: tokens = [100], P = 50
Output: 0
Example 2:
Input: tokens = [100,200], P = 150
Output: 1
Example 3:
Input: tokens = [100,200,300,400], P = 200
Output: 2
Note:
tokens.length <= 1000
0 <= tokens[i] < 10000
0 <= P < 10000
2 尝试解
2.1 分析
一个整型数组,代表若干筹码,玩家有一个初始的能量 。对于每个筹码,有两种选择:
消耗筹码代表的能量,分数+1;获得筹码代表的能量,分数-1。问分数的最大值。
首先既然每次对筹码操作得到或减去的分数相同,那么要消耗能量,肯定要从能量最小的开始;要获得能量,肯定要从能量最大的开始。所以先将数组排序,然后左端开始,重复获取最小的筹码,直到能量不足,或者左端超过右端,筹码用尽,游戏结束。如果未结束,且此时分数为零,说明初始能量比最小的筹码还小,游戏结束;如果左端右端重合,游戏结束,因为即使获取了这个筹码的能量,也没有别的筹码能继续游戏,反而减少了分数;否则,获取最大筹码的能量,重复上述操作。
2.2 代码
class Solution {
public:
int bagOfTokensScore(vector<int>& tokens, int P) {
int left = 0, right = tokens.size()-1, result = 0;
sort(tokens.begin(),tokens.end());
while(left <= right){
while(left <= right &&tokens[left]<=P){
result ++;
P -= tokens[left];
left++;
}
if(left < right && result > 0){
P += tokens[right];
right--;
result --;
}
else break;
}
return result;
}
};
3 标准解
class Solution {
public:
int bagOfTokensScore(vector<int>& tokens, int P) {
sort(tokens.begin(), tokens.end());
int res = 0, points = 0, i = 0, j = tokens.size() - 1;
while (i <= j) {
if (P >= tokens[i]) {
P -= tokens[i++];
res = max(res, ++points);
} else if (points > 0) {
points--;
P += tokens[j--];
} else {
break;
}
}
return res;
}
};