当前位置: 首页 > news >正文

从零学算法2327

2327.知道秘密的人数
在第 1 天,有一个人发现了一个秘密。
给你一个整数 delay ,表示每个人会在发现秘密后的 delay 天之后,每天 给一个新的人 分享 秘密。同时给你一个整数 forget ,表示每个人在发现秘密 forget 天之后会 忘记 这个秘密。一个人 不能 在忘记秘密那一天及之后的日子里分享秘密。
给你一个整数 n ,请你返回在第 n 天结束时,知道秘密的人数。由于答案可能会很大,请你将结果对 109 + 7 取余 后返回。
示例 1:
输入: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 。(五个人知道秘密)
示例 2:
输入:n = 4, delay = 1, forget = 3
输出:6
解释:
第 1 天:第一个知道秘密的人为 A 。(一个人知道秘密)
第 2 天:A 把秘密分享给 B 。(两个人知道秘密)
第 3 天:A 和 B 把秘密分享给 2 个新的人 C 和 D 。(四个人知道秘密)
第 4 天:A 忘记了秘密,B、C、D 分别分享给 3 个新的人。(六个人知道秘密)
提示:
2 <= n <= 1000
1 <= delay < forget <= n

  • 定义数组know[i]表示恰好在第i天知道秘密的人

  • 那么当 j 在[i+delay,i+forget-1]区间时,第j天的人都会因为之前的人恰好在第i天知道秘密,因此让第j天的人也恰好在这个区间中某一天被分享而知道了秘密

  • 而统计最后结果时,我们只要统计在到第n天时还在遗忘期限内的人即可,即n<=i+forget-1

  •   public int peopleAwareOfSecret(int n, int delay, int forget) {final int MOD = (int)1e9 + 7;int[] know = new int[n + 1];know[1] = 1;long ans = 0;for(int i = 1; i <= n; i++){// 这天以及之后的人来不及遗忘秘密// 而这之前的人都会因为经过了forget天还没到n天而遗忘秘密,所以不计入ansif(i + forget - 1 >= n){ans += know[i];}for(int j = i + delay; j <= Math.min(i + forget - 1, n); j++){know[j] = (know[j] + know[i]) % MOD;}}return (int)(ans % MOD);}
    
  • know[i+delay,i+forget-1] 都加上 know[i],可以用差分数组优化

  • know[1] = 1 -> d[1] = 1know[2] = 0 -> d[2] = 0 - 1 = -1

  •   public int peopleAwareOfSecret(int n, int delay, int forget) {final int MOD = (int)1e9 + 7;int[] d = new int[n + 1];// know[] = [0,1,0,0,...]// 对应d[] = [0,1,-1,0,...]d[1] = 1;d[2] = -1;int know = 0;long ans = 0;for(int i = 1; i <= n; i++){// know 相当于之前的 know[i],因为d[0]+...+d[i] = know[i]know = (know + d[i]) % MOD;if(i + forget - 1 >= n){ans += know;}// know[i+delay,i+forget-1]的人都增加know[i]// 对应d[i+delay] += know, d[i+forget] -= knowif(i + delay <= n){d[i + delay] = (d[i + delay] + know) % MOD;}if(i + forget <= n){d[i + forget] = (d[i + forget] - know + MOD) % MOD;}}return (int)(ans % MOD);}
    
  • 前缀和:设 sum[i] = 第i天结束时,累计知道过秘密的人数

    • 我们要的结果是在第 n - forget + 1 到第 n 天新增的知道秘密的人数,这些人还没来得及遗忘,是到第 n 天还记得秘密的人
    • 第i到j天知道的人数为sum[j] - sum[i-1]
    • 所以最终结果为 sum[n] - sum[n - forget]
  • 从第一天开始不断累加今天新增的知道秘密的人数know,就能得到最终的 sum

    • 即不断 sum[j] = sum[j - 1] + know
  • 最终难点就是计算出 know,在第 j 天新增知道的秘密的人数其实就是在第 j 天能够分享秘密的人数总和

    • 假设在第 k 天知道秘密,第 j 天能分享,首先要经过 delay 天
      • j >= k + delay -> k <= j - delay
    • 其次不能经过 forget 天否则会忘记
      • j <= k + forget - 1 -> k >= j - forget + 1
    • 也就是说在第 j-forget+1 ~ j - delay 天之间知道秘密的总人数就是 know,你会发现这不就是 sum[j - delay] - sum[j-forget]
  •   public int peopleAwareOfSecret(int n, int delay, int forget) {final int MOD = (int)1e9 + 7;int[] sum = new int[n + 1]; // known 数组的前缀和sum[1] = 1;for(int j = 2; j <= n; j++){// 第 j 天新增的知道秘密的人数int know = (sum[Math.max(j-delay,0)] - sum[Math.max(j-forget,0)]) % MOD;// 前几天知道的总人数 + 新增的等于到第j天为止知道的总和sum[j] = (sum[j-1] + know) % MOD;}int ans = sum[n] - sum[Math.max(n-forget, 0)];return (int)(ans % MOD + MOD)%MOD; // 保证答案非负}
    

文章转载自:

http://J3xlxV2G.sgxkq.cn
http://u9A2pdyP.sgxkq.cn
http://ZgIgqfZB.sgxkq.cn
http://owbkRfOp.sgxkq.cn
http://V90EBXoO.sgxkq.cn
http://t7m93Op3.sgxkq.cn
http://UxuiihIR.sgxkq.cn
http://1isQ8VTG.sgxkq.cn
http://KQpp8IvM.sgxkq.cn
http://PERDOiB8.sgxkq.cn
http://lVI8iiXs.sgxkq.cn
http://QtS1OhZm.sgxkq.cn
http://BOF4Orer.sgxkq.cn
http://wTVCRcYD.sgxkq.cn
http://FNlPh7rj.sgxkq.cn
http://MUjjxY6i.sgxkq.cn
http://sll3xPSz.sgxkq.cn
http://B4oCcR1q.sgxkq.cn
http://Qf7qGlC7.sgxkq.cn
http://PvqD7SMb.sgxkq.cn
http://JKZwuGGZ.sgxkq.cn
http://xPQNTip8.sgxkq.cn
http://3V1b1dXI.sgxkq.cn
http://zn5kgnRl.sgxkq.cn
http://kvy79nIT.sgxkq.cn
http://ZDVUXfsQ.sgxkq.cn
http://znphpJ3M.sgxkq.cn
http://vnzGkGLE.sgxkq.cn
http://IzNttIJP.sgxkq.cn
http://B1nXT3Is.sgxkq.cn
http://www.dtcms.com/a/380350.html

相关文章:

  • 【C++】:list容器全面解析
  • 渲染农场多少钱一小时
  • IDEA试用过期,无法登录,重置方法
  • IP验证学习之case编写
  • 通过Dockerfile构建Docker镜像并训练模型
  • 操作系统内核架构深度解析:从微内核到宏内核的设计哲学与性能权衡
  • IIS运行账户设置记录
  • 服务管理 systemctl
  • HTTP与HTTPS
  • devextreme-vue表格设置可复制粘贴
  • Go 语言 PDF 生成库综合比较与实践指南
  • 图技术重塑金融未来:悦数图数据库如何驱动行业创新与风控变革
  • 金融数据---ETF日线行情数据
  • Vue 整体框架全面解析
  • 鸿蒙 NEXT应用国际化:时区与夏令时处理
  • 海外代理IP平台哪家好?高纯净度稳定住宅代理IP平台推荐
  • 锂电池行业生产中 AI 应用场景与价值分析
  • MySQL 命令行导入 SQL 文件
  • 3DMAX自动材质开关插件AutoMaterial安装和使用方法
  • Ubuntu C编程 (make工具和Makefile的引用)
  • 9.12AI简报丨腾讯投资AI游戏平台,B站开源AniSora V3
  • 家庭健康智能终端:解锁智能家居时代的健康管理
  • 机器视觉检测如何使用360 度全景成像镜头进行AI 瑕疵检测
  • # Windows驱动程序开发入门:从原理到实践
  • 在Webpack中集成Vite的开发服务器时,可能会遇到哪些兼容性问题?如何解决?
  • DCA1000 AWR1843 环境安装
  • 零公网IP 跨设备协同OctoPrint+cpolar3D打印远程管理新方法
  • 【Spring】原理解析:Spring Boot 自动配置的核心机制与实战剖析
  • Linux挂在目录空间问题--随手
  • Linux:线程控制详解