七月集训----队列

目录

问题一:2327. 知道秘密的人数

问题思路:

代码:


问题一:2327. 知道秘密的人数

问题描述: 

在第 1 天,有一个人发现了一个秘密。

给你一个整数 delay ,表示每个人会在发现秘密后的 delay 天之后,每天 给一个新的人 分享 秘密。同时给你一个整数 forget ,表示每个人在发现秘密 forget 天之后会 忘记 这个秘密。一个人 不能 在忘记秘密那一天及之后的日子里分享秘密。

给你一个整数 n ,请你返回在第 n 天结束时,知道秘密的人数。由于答案可能会很大,请你将结果对 10^9 + 7 取余 后返回。

 

问题思路:

题目中的人数分为三个部分:①已经知道秘密,同时也可以分享秘密的人数(cnt_A)

②已经知道秘密,但是还不能分享秘密的人数(cnt_B)

③已经遗忘掉秘密,不计入最后的结果的人数(cnt_C)

一开始自己的思路是先假设所有人都不会忘记,直接计算知道秘密的人数(cnt_A+cnt_B)最后减去遗忘秘密的人数(cnt_C),发现处理遗忘秘密人数不太好操作,所以看着题解修正了自己的思路。

大概思路如下:

建立数组f[n]用来存储从1-n每天的第一类人的人数(即cnt_A).

建立i 从0到n的循环,先判断i+delay是否大于n,如果大于,则意味着此时知道秘密,但不能分享的第二类人数由当前的cnt_A与cnt_B组成(cnt_b = (cnt_b + f[i]),即可以分享秘密的人已经没有时间分享秘密了。

接着在[i+delay, i+forget]这个区间内,计算f[]的值(注意i+forget不要越界)

题目所要求的结果即变成:f[n-1]+cnt_B。

代码:


int peopleAwareOfSecret(int n, int delay, int forget){
  int M = pow(10, 9)+7;
    int f[1010];
    memset(f,0,sizeof(int) * 1010);
    f[0] = 1; //第一天有1个人知道
    int cnt_b = 0;
    for(int i=0; i<n; i++)   
    {
      if(i + delay >=n)
        cnt_b = (cnt_b + f[i]) % M;
        for(int j= i+delay; j< fmin(i+forget,n); j++)    //在[i+delay, i+forget]这个区间内更 
                                                           新A类人数
          f[j] = (f[j]+f[i]) %M;
    }

    return (f[n-1] + cnt_b) % M;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值