【每日一题 | 动态规划】访问完所有房间的第一天

这篇具有很好参考价值的文章主要介绍了【每日一题 | 动态规划】访问完所有房间的第一天。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Tag

【动态规划】【数组】【2024-03-28】


题目来源

1997. 访问完所有房间的第一天

访问完所有房间的第一天,LeetCode每日一题,动态规划,数组,C++,2024-03-28

解题思路

方法一:动态规划

定义状态

定义 f[i] 表示第一次到达房间 i 的日期编号。

根据题意,首次(第 1 次)访问房间 i 时,因为 1 是计数,所以下一次一定会访问房间 j = nextVisit[i]。只有访问次数达到偶数才能访问右边的下一个房间,所以在第一次访问 i 房间时,我们一定访问了偶数次(2次)i 左边的房间。

换言之,第一次到达房间 i 时,[0, ..., i-1] 房间均被访问了,所以答案直接返回 f[n-1] 即可。

转移关系

第一次到达房间 i 是由第二次到达房间 i-1 递推得到的。第一次到达房间 i-1 的日期编号为 f[i-1],这时候需要花费一天的时间回退到房间 nextVisit[i-1] (因为房间 i-1 是第一次访问)。

此时,房间 nextVisit[i-1] 的访问次数为奇数,我们需要从该房间走(访问)到房间 i-1,花费时间为 f[i-1] - f[nextVisit[i-1]]。这时房间 i-1 被访问了偶数次,可以直接耗时一天走到房间 i。于是有转移关系:

f [ i ] = f [ i − 1 ] + 1 + f [ i − 1 ] − f [ n e x t V i s i t [ i − 1 ] ] + 1 = 2 ∗ f [ n − 1 ] − f [ n e x t V i s i t [ i − 1 ] ] + 2 f[i] = f[i-1] + 1 + f[i-1] - f[nextVisit[i-1]] + 1 \\= 2*f[n-1] - f[nextVisit[i-1]] + 2 f[i]=f[i1]+1+f[i1]f[nextVisit[i1]]+1=2f[n1]f[nextVisit[i1]]+2

base case

初始状态为 f[0] = 0,表示第一次访问房间 0 的日期为 0。

实现代码

class Solution {
public:
    int firstDayBeenInAllRooms(vector<int>& nextVisit) {
        int n = nextVisit.size();
        vector<long long> f(n);
        const int MOD = 1e9 + 7;
        for (int i = 1; i < n; ++i) {
            f[i] = (2 * f[i-1] - f[nextVisit[i-1]] + 2 + MOD) % MOD;
        }
        return f[n-1];
    }
};

复杂度分析

时间复杂度: O ( n ) O(n) O(n) n n n 为数组 nextVisit 的长度。

空间复杂度: O ( n ) O(n) O(n)


写在最后

如果您发现文章有任何错误或者对文章有任何疑问,欢迎私信博主或者在评论区指出 💬💬💬。

如果大家有更优的时间、空间复杂度的方法,欢迎评论区交流。

最后,感谢您的阅读,如果有所收获的话可以给我点一个 👍 哦。文章来源地址https://www.toymoban.com/news/detail-852933.html

到了这里,关于【每日一题 | 动态规划】访问完所有房间的第一天的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • ( 动态规划) 1035. 不相交的线 ——【Leetcode每日一题】

    难度:中等 在两条独立的水平线上按给定的顺序写下 nums1 和 nums2 中的整数。 现在,可以绘制一些连接两个数字 nums1[i] 和 nums2[j] 的直线,这些直线需要同时满足满足: nums1[i] == nums2[j] 且绘制的直线不与任何其他连线(非水平线)相交。 请注意,连线即使在端点也不能相交

    2024年02月05日
    浏览(33)
  • ( 动态规划) 516. 最长回文子序列 ——【Leetcode每日一题】

    难度:中等 给你一个字符串 s ,找出其中最长的回文子序列,并返回该序列的长度。 子序列定义为:不改变剩余字符顺序的情况下,删除某些字符或者不删除任何字符形成的一个序列。 示例 1: 输入:s = “bbbab” 输出:4 解释:一个可能的最长回文子序列为 “bbbb” 。 示例

    2024年02月06日
    浏览(32)
  • (动态规划) 132. 分割回文串 II ——【Leetcode每日一题】

    难度:困难 给你一个字符串 s ,请你将 s 分割成一些子串,使每个子串都是回文。 返回符合要求的 最少分割次数 。 示例 1: 输入:s = “aab” 输出:1 解释:只需一次分割就可将 s 分割成 [“aa”,“b”] 这样两个回文子串。 示例 2: 输入:s = “a” 输出:0 示例 3: 输入:

    2024年02月15日
    浏览(31)
  • [Week 18] 每日一题(C++,动态规划,线段树,数学)

    目录 [Daimayuan] T1 最长公共子序列(C++,DP,二分) 输入格式 输出格式 数据范围 输入样例 输出样例 解题思路 [Daimayuan] T2 喵喵序列(C++,序偶) 题目描述 输入格式 输出格式 样例输入 样例输出 样例说明 数据范围 双倍经验 解题思路: [Daimayuan] T3 漂亮数(C++,字符串) 输入

    2023年04月24日
    浏览(44)
  • 罗勇军 →《算法竞赛·快冲300题》每日一题:“乘积” ← 动态规划

    【题目来源】 http://oj.ecustacm.cn/problem.php?id=1781 http://oj.ecustacm.cn/viewnews.php?id=1023 【题目描述】 给你一个长度为 n 的序列,序列中的元素只包括 1 和 -1。 请问有多少个连续的子序列乘积为正数。 【输入格式】 输入第一行为正整数 n。(n不超过10^6) 第二行包含 n 个整数。 【输

    2024年02月11日
    浏览(38)
  • [Week 19]每日一题(C++,数学,并查集,动态规划)

    目录 [Daimayuan] T1 倒数第n个字符串(C++,进制) 输入格式 输出格式 样例输入 样例输出 解题思路 [Daimayuan] T2 排队(C++,并查集) 输入格式 输出格式 样例输入1 样例输出1 样例输入2 样例输出2 样例输入3 样例输出3 数据规模 解题思路 [Daimayuan] T3 素数之欢(C++,BFS) 数据规模

    2024年02月02日
    浏览(37)
  • 【每日一题】ABC248C - Dice Sum | 动态规划 |简单

    原题链接 构造一个长度为 n n n 的整数数组 a a a ,满足如下两个条件: 1 ≤ a i ≤ m 1leq a_ileq m 1 ≤ a i ​ ≤ m ∑ a i ≤ k sum a_ileq k ∑ a i ​ ≤ k 问可以构造出多少种不同的数组 a a a 。 1 ≤ n , m ≤ 50 1leq n,mleq 50 1 ≤ n , m ≤ 50 n ≤ k ≤ n × m nleq kleq ntimes m n ≤ k ≤ n × m

    2024年02月09日
    浏览(25)
  • (动态规划) 剑指 Offer 42. 连续子数组的最大和 ——【Leetcode每日一题】

    难度:简单 输入一个整型数组,数组中的一个或连续多个整数组成一个子数组。求所有子数组的和的最大值。 要求时间复杂度为 O(n) 。 示例1: 输入: nums = [-2,1,-3,4,-1,2,1,-5,4] 输出: 6 解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。 提示 : 1 = a r r . l e n g t h = 1 0 5 1 = arr.length = 10^

    2024年02月11日
    浏览(37)
  • 【每日一题Day208】LC1335工作计划的最低难度 | 动态规划

    工作计划的最低难度【LC1335】 你需要制定一份 d 天的工作计划表。工作之间存在依赖,要想执行第 i 项工作,你必须完成全部 j 项工作( 0 = j i )。 你每天 至少 需要完成一项任务。工作计划的总难度是这 d 天每一天的难度之和,而一天的工作难度是当天应该完成工作的最大

    2024年02月05日
    浏览(58)
  • (动态规划) 剑指 Offer 60. n个骰子的点数 ——【Leetcode每日一题】

    难度:中等 把 n 个骰子扔在地上,所有骰子朝上一面的点数之和为 s 。输入 n ,打印出s的所有可能的值出现的概率。 你需要用一个浮点数数组返回答案,其中第 i 个元素代表这 n 个骰子所能掷出的点数集合中第 i 小的那个的概率。 示例 1: 输入: 1 输出: [0.16667,0.16667,0.16667,

    2024年02月11日
    浏览(29)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包