zoukankan      html  css  js  c++  java
  • Leetcode 周赛#202 题解

    本周的周赛题目质量不是很高,因此只给出最后两题题解()。

    1552 两球之间的磁力 #二分答案

    题目链接

    题意

    n个空篮子,第i个篮子位置为position[i],现希望将m个球放到这些空篮子,使得任意两球间最小磁力最大。(其中,磁力简化为两点位置之差)

    分析

    该题是二分答案的裸题,详细见代码

    class Solution {
    public:
        bool Judge(vector<int>& a, int x, int m){
            int cnt = 1,lastpos = a[0];
            for (int i = 1; i < (int)a.size(); i++){
                if(a[i] - lastpos >= x){ //两点间距是否大于答案x
                    cnt++;
                    lastpos = a[i];
                }
                if(cnt == m) return true;
            }
            return false;
        }
        int maxDistance(vector<int>& position, int m) { //该二分算法,是考虑[1, n+1)
            sort(position.begin(), position.end()); //记得先排序!!!
            int lo = 0x3f3f3f3f;
            int hi = position[position.size() - 1] - position[0] + 1; //确定两个篮子最大间距,为二分的上界,注意要+1!!!
            for (int i = 1; i < (int)position.size(); i++){
                int delt = position[i] - position[i - 1]; //确定两个篮子的最小间距,为二分的下界
                lo = min(delt, lo);
            }
            while(lo < hi){
                int mid = (lo + hi) >> 1;
                if(Judge(position, mid, m)) //估计答案
                    lo = mid + 1; //答案可以再高一些
                else
                    hi = mid; //说明该答案下的间距无法将所有球放完
            }
            return lo-1;
        }
    };
    

    1553 吃掉N个橘子的最少天数 #记忆化搜索

    题目链接

    题意

    给定n(<= 2e9)个橘子,每一天你只能从以下三种方案中选择一种:

    • 吃掉一个橘子
    • 若剩余橘子数n能被2整除,那么你可以吃掉n/2个橘子
    • 若剩余橘子数n能被3整除,那么你可以吃掉2*(n/3)个橘子

    现要求吃掉这n个橘子的最少天数。

    分析

    容易知道,当n>3时,吃掉n/2个橘子,剩余橘子数即为n/2;吃掉2*(n/3)个橘子,剩余橘子树即为n/3

    那我们先预处理,将n$leq$3的情况记录下来。接下来考虑转移方程。

    起初我考虑有三个转移方向:n-1n/2n/3,并用数组记忆化。在如此庞大的数据范围,不但数组无法承受,而且会分出更多的子问题。

    为了应对空间问题,可以考虑用map来记忆化。

    为了应对时间问题,我们分析到,对于当前剩余橘子数n

    • 方案二分析:(n Mod 3 = 0, 1, 2),余数为0,显然吃掉n/3个橘子即可;余数为1时,说明我们需要用n/3天的时间将3的倍数个橘子吃完,最后剩下一个橘子,需要1天;同理,余数为2时,说明我们用n/3天将3的倍数个橘子吃完后,还需要用两天时间(使用方案一)将剩下2个橘子吃完。
    • 方案三如方案二分析同理,我们要用n/2将2的倍数个橘子吃完后,还需要(n Mod 2)天(使用方案一,且已经预处理过)吃掉剩余的橘子。

    因此,我们只需要交给程序去考虑当前的n是选择方案二更优还是方案三,自顶而下向下递归。无需再考虑n-1的方向,同时无需考虑当前的n是否被3整除/被2整除。转移方程见下方代码。

    class Solution {
    private:
        unordered_map<int, int> dp;
    public:
        int minDays(int n) {
            if(n == 1)           return dp[1] = 1;
            else if(n == 2)      return dp[2] = 2;
            else if(n == 3)      return dp[3] = 2;
            else if(dp.count(n)) return dp[n];
            else return dp[n] = min(minDays(n / 3) + 1 + n % 3,
                                    minDays(n / 2) + 1 + n % 2);
            
        }
    };
    

    在笔记本最后几点电量写完题解qaq

  • 相关阅读:
    linux下进度条的简单实现
    简单vim配置
    Linux下find指令
    Python学习笔记十三_操作数据库
    Python学习笔记十二_常用模块
    Python学习笔记十一_函数返回多值、列表生成式、循环多变量、入参格式声明
    Python学习笔记十_模块、第三方模块安装、模块导入
    Python函数及json练习_双色球
    Python函数及json练习_商品管理
    Python json练习_读写文件函数
  • 原文地址:https://www.cnblogs.com/J-StrawHat/p/13524314.html
Copyright © 2011-2022 走看看