题解 | #附加题# 动态规划

附加题

https://www.nowcoder.com/practice/58b04ed2865f4ff4921290f1bd4ee486

一开始理所当然地用模拟的方法做,但是怎么都是时间超时,才仔细考虑了一下应该用动态规划

定义dp[i]为第一次到达第i号房间所用的步数

由题意知,若要到达第i号房间,则必须到达第i-1号至少两次:

第一次到达i-1号时,再走1步则跳回到前面的某个房间,记为tp[i-1]

此时必须重新返回第i-1号房间,那么所花费的步数即为:

到达i−1号房所需的步数-到达tp[i−1]号房所需的步数

dp[i-1]-dp[tp[i-1]]

综上dp[i]=(dp[i-1]+1)+(dp[i-1]-dp[tp[i-1]])+1

最后的+1是第二次到达i-1号房时再走一步才到i

也可以合并同类项:dp[i]=2*dp[i-1]-dp[tp[i-1]]+2

由于题目提示了要取余1000000007,因此需要特殊处理

#include <iostream>
#include <vector>
#define MOD 1000000007
using namespace std;

int main() {
    int n;
    while (cin >> n) {
        vector<long long> tp(n + 1);
        int room;
        for (int i = 1 ; i <= n; i++) {
            cin >> room;
            tp[i] = room;
        }
        vector<long long> dp(n + 2, 0);
        for (int i = 2; i <= n + 1; i++) {
            dp[i] = (dp[i - 1] + 1 + dp[i - 1] - dp[tp[i - 1]] + 1 + MOD) % MOD;
        }
        cout << dp[n + 1] << endl;
    }
    return 0;
}

时间复杂度:O(n),用于遍历数组

空间复杂度:O(n),用于存储数组

全部评论

相关推荐

面了100年面试不知...:今年白菜这么多,冬天可以狂吃了
点赞 评论 收藏
分享
12-27 22:28
门头沟学院 Java
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务