题目:
你的初始能量为 P
,初始分数为 0
,只有一包令牌。
令牌的值为 token[i]
,每个令牌最多只能使用一次,可能的两种使用方法如下:
- 如果你至少有
token[i]
点能量,可以将令牌置为正面朝上,失去token[i]
点能量,并得到1
分。 - 如果我们至少有
1
分,可以将令牌置为反面朝上,获得token[i]
点能量,并失去1
分。
在使用任意数量的令牌后,返回我们可以得到的最大分数。
样例:
示例 1:
输入:tokens = [100], P = 50
输出:0
示例 2:
输入:tokens = [100,200], P = 150
输出:1
示例 3:
输入:tokens = [100,200,300,400], P = 200
输出:2
提示:
tokens.length <= 1000
0 <= tokens[i] < 10000
0 <= P < 10000
思路:
一开始直接从小到大把令牌排序之后,就直接开始从第一个令牌开始判大小,能量够就直接翻,直到不能翻了为止,然后把能量最大的牌盖过去赚取能量。再从小到大开始翻牌赚取分数。
然后过样例的时候发现,非常不严谨,很多情况没有考虑到,比如只有两张牌的情况下,翻了一张再盖一张之后,分数为零,有了能量但是无牌可翻了,然而答案明显不是0。
所以补足了判定条件,后面过样例又出现了分数不是最大的情况。才开始循环嵌套并且把分数每次循环进行判别大小,将更大的分数更新。代码如下。
我的代码:
class Solution {
public:
int bagOfTokensScore(vector<int>& tokens, int P) {
if(tokens.empty())
return 0;
int score=0;
int num=0;
for(int ii=0;ii<tokens.size()-1;ii++)
{
for(int jj=0;jj<tokens.size()-1-ii;jj++)
{
if(tokens[jj]>tokens[jj+1])
{
int temp=tokens[jj];
tokens[jj]=tokens[jj+1];
tokens[jj+1]=temp;
}
}
}//冒泡排序
for(int i=0;i<tokens.size();i++)
{
if(P>=tokens[i])
{
score++;
P=P-tokens[i];
tokens[i]=-1;
}
}//从小到大开始翻牌疯狂赚分直到能量不够,并且把被翻的牌能量值赋值为负,后面好进行过滤
num=score;//初始分数赋值
for(int i=tokens.size()-1;i>0;i--)
{
if(score>0&&tokens[i]>0&&tokens.size()>3)//大于3是为了避免翻一张扣一张无牌可翻的情况和过滤掉能量为负值的已翻牌
{
score--;
P=P+tokens[i];
tokens[i]=-1;
}//从能量最大的牌开始扣赚能量
for(int i=0;i<tokens.size();i++)
{
if(tokens[i]>0&&P>=tokens[i])
{
P=P-tokens[i];
tokens[i]=-1;
score++;
}
} //从小到大开始翻牌赚分
if(num<score)
num=score;//每次循环后将更大的分数更新
}
return num;
}
};