力扣5865. 访问完所有房间的第一天

这是2021-9-5的一道周赛题,当时以为是要用差分数组,但是发现这么做复杂度太高了,并且容易写错,看了题解的dalao才恍然大悟,就是一道普通但很难想到的dp(自己tcl /(ㄒoㄒ)/~~)


原题:[5865. 访问完所有房间的第一天](https://leetcode-cn.com/problems/first-day-where-you-have-been-in-all-the-rooms/)

解释在注释

// dp[i]代表可以离开i的总天数的和, 下文dp的下标从1开始
// 主要分两种情况:
// 1、当前的nextVisit是自己,那么就是直接可以从前一天到今天,那么  dp[i] = dp[i-1] + 2
// 2、当天的nextVisit是之前的房间j,那么就需要重新再走一次j~i-1, 根据前缀和,再走一次的天数是dp[i-1]-dp[nextVisit[i-1]],然后再加上之前走过的和自己的2次:
//    dp[i] = dp[i-1]-dp[nextVisit[i-1]] + dp[i-1] + 2
// 上代码
#define ll long long
class Solution {
public:
    int firstDayBeenInAllRooms(vector<int>& nextVisit) {
        ll MOD = 1e9+7;
        int n = nextVisit.size();
        vector<ll> dp(n+1, 0);
        for(int i=1; i<=n-1; i++){
            // 公式里面MOD的原因是前面mod的结果可能比当前小,所以每一步都要加上mod防止出现负数
            if(nextVisit[i-1]==i-1)
                dp[i] = (dp[i-1]+2+MOD)%MOD;
            else
                dp[i] = (dp[i-1]-dp[nextVisit[i-1]] + dp[i-1] + 2+MOD) % MOD;
        }
        return dp[n-1];
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值