leetcode6112.6112. 装满杯子需要的最短总时长(简单,周赛)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
思路一:贪心
具体思路:尽量让产生0最晚,这样就一直有正整数可以选,因此每次选最大的两个

class Solution {
public:
    int fillCups(vector<int>& amount) {
   
        priority_queue<int> pq;
        for (int i = 0; i < 3; ++i) {
            if (amount[i]) pq.push(amount[i]);
        }
        int ans = 0;
        while (!pq.empty()) {
            ans++;
            if (pq.size() >= 2) {
                int a = pq.top();
                pq.pop();
                int b = pq.top();
                pq.pop();
                if (--a) pq.push(a);
                if (--b) pq.push(b);
            }else {
                int a = pq.top();
                pq.pop();
                if (--a) pq.push(a);
            } 
        }
        return ans;
    }
};

思路二:数学思想
在这里插入图片描述

class Solution {
public:
    int fillCups(vector<int>& amount) {

        sort(amount.begin(), amount.end());
        if (amount[0] + amount[1] <= amount[2]) return amount[2];
        return (amount[0] + amount[1] + amount[2] + 1) / 2;
    }
};

思路三:暴力dfs+记忆化+字符串hash

unordered_map<long long, int> cache;  //
class Solution {
public:
    const long long base = 131;
    
    int dfs(vector<int>& amount) {
        if (*max_element(amount.begin(), amount.end()) == 0) {
            return 0;
        }
        long long tmp2 = base * base * amount[0] + base * amount[1] + amount[2];
        if (cache.count(tmp2)) 
            return cache[tmp2];

        int ans = INT_MAX;
        if (amount[0] > 0 && amount[1] > 0) { //
            amount[0]--;
            amount[1]--;
            ans = min(ans, dfs(amount)+1);
            amount[0]++;
            amount[1]++;
        }
        if (amount[0] > 0 && amount[2] > 0) {
            amount[0]--;
            amount[2]--;
            ans = min(ans, dfs(amount)+1);
            amount[0]++;
            amount[2]++;
        }
        if (amount[2] > 0 && amount[1] > 0) {
            amount[2]--;
            amount[1]--;
            ans = min(ans, dfs(amount)+1);
            amount[2]++;
            amount[1]++;
        }
        if (amount[0] > 0) {
            amount[0]--;
            ans = min(ans, dfs(amount)+1);
            amount[0]++;
        }
        if (amount[1] > 0) {
            amount[1]--;
            ans = min(ans, dfs(amount)+1);
            amount[1]++;
        }
        if (amount[2] > 0) {
            amount[2]--;
            ans = min(ans, dfs(amount)+1);
            amount[2]++;
        }
        return cache[tmp2] = ans;
    }
    int fillCups(vector<int>& amount) {
        int ans = dfs(amount);
        return ans;
    }
};

需要注意的两个地方:
1:unordered_map<long long, int> cache; 放到class类外能过,放到类内过不了。
放到类外cache是所有测试用例共享的,放到类内每个用力都得执行一遍,因此速度会更快。
2:

cache[key] = min(cache[key], dfs({amount[0] - 1, amount[1] - 1, amount[2]}) + 1);

如果用上面写法的话,发生超时,参数可以优化下:还是使用amount,避免产生临时的vector

if (amount[0] > 0 && amount[1] > 0) { //
       amount[0]--;
       amount[1]--;
       ans = min(ans, dfs(amount)+1);
       amount[0]++;
       amount[1]++;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值