7-15 跳一跳 (100 分)

Drizzle 面前有一条由一堆非负整数组成的道路,从第一个数字起步,每次他都能跳出不大于当前数字的距离,每个数字之间的距离为1,那么他最少需要跳多少次才能到达终点?
要求:
输入:第一行输入道路中数字的个数n也就是道路的长度,第二行输入这n个数字
下面展示一些 内联代码片
下面展示一些 内联代码片

5
2 3 1 1 4

输出:输出一个数字,表示最少跳跃次数
下面展示一些 内联代码片

2

解释: 跳到最后一个位置的最小跳跃数是 2。从下标为 0 跳到下标为 1 的位置,跳 1 步,然后跳 3 步到达数组的最后一个位置。

范围:
对于 20% 的数据:n≤100
对于 100% 的数据:n≤1000000
所有整数元素在int范围内
下面展示一些 内联代码片
下面展示一些 内联代码片

思路:在能跳的区间里先筛选出最大的数,再从最大的数到能跳到的区间里筛选出最优的位置,一直到能跳到终点的地方终止。
#include<iostream>
#include<vector>
using namespace std;
int main(){
	int t;
	cin>>t;
	vector<int>v;
	for(int i=0;i<t;i++){
		int a;
		cin>>a;
		v.push_back(a);
	}
	int count=0;//count对需要跳几次计数 
	int max=0,temp2=0,max1=0;
	t--;//因为从第一个开始,所以需要跳的距离减1 
	while(1){
		max1=0;
		temp2=max;
		if(v[temp2]>=t){//如果能直接跳到终点,那就跳过去结束循环 
			count++;
			break;
		}
		else{
			max=temp2+v[temp2];//将能跳到的最远的地方max初始化成能跳到的范围中最后一个位置的下标 
			for(int j=temp2+1;j<=temp2+v[temp2];j++)if(v[j]>=v[max]&&v[j]+j-temp2>v[temp2])max=j;
			/*在能跳到的下标(【temp2+1,temp2+v[temp2]】筛选出最大的数) 
			且这个数能跳出这个范围*/ 
			max1=v[max]+max;//储存第一个for循环中跳到的位置 
            for(int j=max;j<=temp2+v[temp2];j++)
			//再次在最大的数和结尾筛选出最远的 ,因为仅仅是最大的并不能满足跳的最优
			//没有这个的话最后两个测试点是错的 
			{
				if(v[j]+j>max1){
					max1=v[j]+j;
					max=j;
				}
			}
			t-=max-temp2;//跳完剩余的距离 
			count++;//步数加1 
		}	
	}	
	cout<<count;
	return 0;
}
上一篇:【算法题】动态规划-旅行


下一篇:2021-08-031179 最大的最大公约数