Leetcode 948:令牌放置

题目描述

你的初始能量为 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

提示:

  1. tokens.length <= 1000
  2. 0 <= tokens[i] < 10000
  3. 0 <= P < 10000

解题思路

个人感觉题目容易给人误解,

  • 如果我们至少有 1 分,可以将令牌置为反面朝上,获得 token[i] 点能量,并失去 1 分。

本人错误的理解成正面朝上的然后再消耗一点得分使反面朝上,然后看评论区大佬的解答才明白不是这么回事。其实应该说是消耗一点能量获得一张令牌的tokens[i]值。然后可以使用双指针和贪心解答,先对所有令牌排序,用能量尽可能多的反转牌面值小的令牌,消耗一点得分去获得尽可能多的能量。用i指向要消耗最小能量获得得分的卡牌索引,j指向消耗一点得分获得最大能量的卡牌,外层循环控制条件是当前P大于等于tokens[i]表示可以反转令牌获得一分,或则可能至少还有一张没有反转的令牌并且scores大于0表示可以消耗一分获得能量。

void qsort(vector<int>& tokens,int l,int r){
        if(l < r){
            int i = l,j = r;
            int tmp = tokens[i];
            while(i<j){
                while(i<j && tokens[j] >= tmp) j--;
                tokens[i] = tokens[j];
                while(i<j && tokens[i] < tmp) i++;
                tokens[j] = tokens[i];
            }
            tokens[i] = tmp;
            qsort(tokens,l,i-1);
            qsort(tokens,i+1,r);
        }
    }
    int bagOfTokensScore(vector<int>& tokens, int P) {
        int len = tokens.size();
        qsort(tokens,0,len-1);
        int i = 0,j=len-1,scores = 0;
        while((i<=j && P>=tokens[i]) || (i<j && scores > 0)){
            while(i<=j && P>=tokens[i]){
                P-=tokens[i++];
                scores++;
            }
            if(i>=j) break;
            else if(scores > 0){
                P+=tokens[j--];
                scores--;
            }
        }
        return scores;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值