题解 | #过桥#

过桥

https://ac.nowcoder.com/acm/contest/11217/F

F 过桥

题意

有n个 方块,每一个方块都一个数aia_{i} ,为正数可以往前跳,跳到 iii+a[i]i+a[i],负数可以往回跳 可以跳到11i+a[i]i+a[i]

思路

这个题目有很明显的转移,且数据范围较小,可以采用动态规划。 假设 dp[i]dp[i] 表示到达第 i 个方块的最短用时。由于负数相当于往回走,用时肯定更长,负数肯定可以直接跳过,有负数可能导致不能遍历到第 n 个 方块,如果可以遍历到第 n 个方块直接输出 dp[n]dp[n] ,如果不能输出 -1 ;

  • 转移方程:
dp[i+a[i]]=min(dp[i]+1,dp[i+a[i]);

负数直接跳过

  • code
#include<bits/stdc++.h>
using namespace std;
int dp[30000],a[20000];

int main(){
    int n;
    cin>>n;
    for(int i=1;i<=n;i++) cin>>a[i],dp[i]=INT_MAX;
    dp[1]=0;
    for(int i=1;i<=n;i++){
        if(a[i]>0){
            for(int j=i+1;j<=i+a[i];j++){
                dp[j]=min(dp[i]+1,dp[j]);
            }
        }
    }
    if(dp[n]==INT_MAX) cout<<-1<<endl;
    else cout<<dp[n]<<endl;
}
全部评论
#include <bits> #define INF 0x3f3f3f3f using namespace std; int n; int a[2010]; int dp[2010]; //从1到i所需要的最小花费 int main() { memset(dp,0x3f3f3f3f,sizeof(dp)); scanf("%d",&n); dp[n]=0; for(int i=1;i<=n;i++) { scanf("%d",&a[i]); } for(int i=n-1;i>=1;i--) { if(a[i]<0) continue; //产生回跳无意义 else if(a[i]>0) //枚举可到达的每个节点,寻找最小值 { for(int j=i+1;j<=i+a[i];j++) { dp[i]=min(dp[i],dp[j]+1); } } } if(dp[1]==0x3f3f3f3f) printf("-1\n"); else printf("%d\n",dp[1]); //system("pause"); return 0; } 我拿java也不对,但是思想没问题,我拿java发现会变成负数,试试C++是不是一样,结果也是这样,给他换一个初始化的值就好</bits>
点赞 回复 分享
发布于 2025-08-22 18:13 辽宁
烙铁你这个不是过了75吗,我给你想想哪里有问题
点赞 回复 分享
发布于 2025-08-22 17:08 辽宁

相关推荐

评论
4
收藏
分享

创作者周榜

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