力扣.300(一个比较隐蔽的dp)

简介: 力扣.300(一个比较隐蔽的dp)
  • 题目


6109. 知道秘密的人数
在第 1 天,有一个人发现了一个秘密。
给你一个整数 delay ,表示每个人会在发现秘密后的 delay 天之后,每天 给一个新的人 分享 秘密。
同时给你一个整数 forget ,表示每个人在发现秘密 forget 天之后会 忘记 这个秘密。
一个人 不能 在忘记秘密那一天及之后的日子里分享秘密。
给你一个整数 n ,请你返回在第 n 天结束时,知道秘密的人数。
由于答案可能会很大,请你将结果对 109 + 7 取余 后返回。
  • 示例


输入:n = 6, delay = 2, forget = 4
输出:5
解释:
第 1 天:假设第一个人叫 A 。(一个人知道秘密)
第 2 天:A 是唯一一个知道秘密的人。(一个人知道秘密)
第 3 天:A 把秘密分享给 B 。(两个人知道秘密)
第 4 天:A 把秘密分享给一个新的人 C 。(三个人知道秘密)
第 5 天:A 忘记了秘密,B 把秘密分享给一个新的人 D 。(三个人知道秘密)
第 6 天:B 把秘密分享给 E,C 把秘密分享给 F 。(五个人知道秘密)
  • 思路


dp存当天新增的人数, 能传播秘密的区间累加 为当天新增的人数, 
当天总人数 为 没忘记秘密的区间累加
当天新增人数计算 为 i + delay 到 i + forget-1 的人数之和
当天所有人数 为 n-forget+1 到 n 的人数之和
需要注意的是,只需要关注累加即可,对于forget的,直接舍弃就可以
每天与之相关联的只有delay和forget之间的数据,符合dp的特征。
  • 解答


class Solution {
    public int peopleAwareOfSecret(int n, int delay, int forget) {
        int mod = (int)1e9 + 7;
        // dp[i] 表示第i天新增的知道秘密的人数
        long[] dp = new long[n + 1];
        // 初始值,第一天有1个人知道
        dp[1] = 1;
        // 遍历n天,分别算出第i天在[i + delay, i + forget)区间内做出贡献的值并进行累加
        for(int i = 1; i < n + 1; i++){
            // 第i天的新增的人数能在下面这个for循环的区间内做出贡献
            for(int j = i + delay; j < i + forget && j < n + 1; j++){
                // 比如dp[3] += dp[1],说明第1天的人可以在第3天传播dp[1]个人
                dp[j] += dp[i];
                dp[j] %= mod;
            }
        }
        long ans = 0;
        // 只要计算出[n + 1 - forget, n + 1) 这个没有遗忘的人数和就是结果,
        // 比如说第6天知道秘密的人数就是 6 + 1 - forget(4),也就是从第3天开始累加人数就可以
        // 第3天之前的人都遗忘了
        for(int i = n + 1 - forget; i < n + 1; i++){
            ans += dp[i];
            ans %= mod;
        }
        return (int)ans;
    }
}


相关文章
|
10月前
|
算法 测试技术 Android开发
LeetCode 周赛上分之旅 #45 精妙的 O(lgn) 扫描算法与树上 DP 问题
学习数据结构与算法的关键在于掌握问题背后的算法思维框架,你的思考越抽象,它能覆盖的问题域就越广,理解难度也更复杂。在这个专栏里,小彭与你分享每场 LeetCode 周赛的解题报告,一起体会上分之旅。
44 2
LeetCode 周赛上分之旅 #45 精妙的 O(lgn) 扫描算法与树上 DP 问题
|
2月前
力扣337.打家劫舍3(树形dp)
力扣337.打家劫舍3(树形dp)
|
1月前
dp表,哈希表,力扣5.最长回文子串力扣1745.分割回文串IV力扣132.分割回文串II优先级队列(堆)是什么下面是手动实现小根堆力扣1046.最后一块石头的重量
dp表,哈希表,力扣5.最长回文子串力扣1745.分割回文串IV力扣132.分割回文串II优先级队列(堆)是什么下面是手动实现小根堆力扣1046.最后一块石头的重量
|
2月前
力扣 790. 多米诺和托米诺平铺(一维dp)
力扣 790. 多米诺和托米诺平铺(一维dp)
|
2月前
|
算法
力扣123. 买卖股票的最佳时机 III(状态dp)
力扣123. 买卖股票的最佳时机 III(状态dp)
|
11月前
|
算法
dp算法 力扣309最佳买卖股票时机含冷冻期
dp算法 力扣309最佳买卖股票时机含冷冻期
|
11月前
|
存储 算法 Java
dp算法 力扣174地下城游戏
dp算法 力扣174地下城游戏
|
2月前
力扣370周赛 -- 第三题(树形DP)
力扣370周赛 -- 第三题(树形DP)
|
11月前
|
算法 Android开发
LeetCode 周赛上分之旅 #41 结合离散化的线性 DP 问题
学习数据结构与算法的关键在于掌握问题背后的算法思维框架,你的思考越抽象,它能覆盖的问题域就越广,理解难度也更复杂。在这个专栏里,小彭与你分享每场 LeetCode 周赛的解题报告,一起体会上分之旅。
54 0
|
11月前
|
算法 测试技术 Android开发
LeetCode 周赛上分之旅 #40 结合特征压缩的数位 DP 问题
学习数据结构与算法的关键在于掌握问题背后的算法思维框架,你的思考越抽象,它能覆盖的问题域就越广,理解难度也更复杂。在这个专栏里,小彭与你分享每场 LeetCode 周赛的解题报告,一起体会上分之旅。
54 0