首页 新闻 会员 周边 捐助

C++问题求解思路

0
悬赏园豆:100 [待解决问题]

【题目描述】
小H发明了一个跳格子的游戏,地板上画了排成一排的n个格子,并以1…n按顺序编号。他规定第i个格子可以跳到第1到第i-1个格子中的任一个,且每个格子有一个不一定相同的反方向的跳跃度a[i],代表第i个格还可以跳到第i+1到i+a[i]个格子中的任一个。现在小H指定其中的一个格子,问从这个格子开始,最少需要连续踩几次格子(起始的格子也算在内),可以跳到第n个格子的后方,即若第k个格子有k+a[i]>n,那么从第k个格子就可以跳到第n个格子的后方。

【输入格式】
输入的第1行包含两个正整数n,m,为格子的数目以及询问的次数。

第2行包含n个正整数,第i个正整数为a[i],即第i个格子向反方向最大跳跃的长度。

第3行包含了m个正整数,为询问从哪一个格子开始,最少要几次跳到第n个格子的后方。

数字之间用空格隔开。

【输出格式】
输出包含1行,这一行有m个正整数,对于每一个询问,输出最少需要踩的格子数,数字之间用空格隔开。 行末换行且没有多余的空格。

【样例输入#1】
5 5
2 4 1 1 1
1 2 3 4 5
【样例输出#1】
2 1 2 2 1
【样例解释#1】
若从第1个格子开始则跳到第2个格子,接着就可以跳到第n个格子的后方。

若从第3个格子开始则同样跳到第2个格子。

若从第4个格子开始可以跳到第2个格子或最后一个格子,接着跳出第n个格子,答案同样为2。

【数据规模】
对于20%的数据,有n≤10;

对于40%的数据,有n≤100,m≤10;

对于60%的数据,有n≤1000,a[i]≤1000,m≤500;

对于100%的数据,有n≤100000,a[i]≤n,m≤50000

dhhus的主页 dhhus | 初学一级 | 园豆:6
提问于:2024-09-01 14:47
< >
分享
所有回答(1)
0

来自AI:
以下是使用动态规划解决此问题的 C++ 代码:

#include <iostream>
#include <vector>
#include <climits>

using namespace std;

vector<int> solve(vector<int>& a, int n) {
    vector<int> dp(n + 1, INT_MAX);
    dp[n] = 0;
    for (int i = n - 1; i >= 1; --i) {
        for (int j = i + 1; j <= min(i + a[i], n); ++j) {
            if (dp[j]!= INT_MAX) {
                dp[i] = min(dp[i], dp[j] + 1);
            }
        }
    }
    return dp;
}

int main() {
    int n, m;
    cin >> n >> m;
    vector<int> a(n + 1);
    for (int i = 1; i <= n; ++i) {
        cin >> a[i];
    }
    vector<int> queries(m);
    for (int i = 0; i < m; ++i) {
        cin >> queries[i];
    }
    vector<int> dp = solve(a, n);
    for (int i = 0; i < m; ++i) {
        cout << dp[queries[i]] << " ";
    }
    cout << endl;
    return 0;
}

这个算法的时间复杂度为 O(n2),其中n是格子的数量。对于较大规模的数据可能会比较耗时,但在题目给定的数据规模内可以满足要求。
思路如下:
定义一个数组 dp,其中 dp[i] 表示从第 i 个格子跳到第 n 个格子后方最少需要踩的格子数。
初始化 dp[n] = 0,因为已经在目标位置。
从后往前遍历每个格子,对于每个格子 i,尝试从 i + 1 到 i + a[i] 的格子中找到最小的 dp 值,并加上 1 作为从格子 i 出发的最小步数。
最后,对于每个查询的起始格子,输出对应的 dp 值。

中华鲟3670 | 园豆:922 (小虾三级) | 2024-09-02 08:45
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册