题目描述
2077年,小南在进行一次常规的宇宙旅行,他要去的星球太远了,直线距离足足有n光年。
但是好消息是:
- 人类已经可以使用任意门了,可以借助建造好的任意门进行传送
- 从小南家门口开始,每隔1光年都会有一道任意门,目标星球上也有
美中不足就是:
- 每道门都有传送的距离限制,假设第i个任意门P[i]=4,那就代表着通过它最远只能从4光年后的那道任意门出来,也就是第(i+4)道门。当然,也可以在第(i+3)道门、第(i+2)道门、第(i+1)道门出来
现在小南拿到了旅途中n个任意门的传送距离限制,记为数组P。他想知道怎么才能用最少的传送次数到达目标星球。
举个例子:
n=5 p=[3, 4, 1, 1, 2]
第0站最远传送距离是3,那么通过它最远能去到3光年后的第3站。
下面介绍两个方案:
1. 他贪心去了最远的第3站,但是第3站的传送距离是1,此时他只能去到第4站。然后在第4站再传送一次到达最终的目的地。总共传送3次
2. 他在第0站只向前传送了1光年,到了第1站。第1站的传送距离有4,可以直接到达目的地了!只需要传送2次
小南觉得这也太酷了,于是拜托你用动态规划方法帮他算算
输入:
第一行,一个整数n。代表着目的地的距离
第二行,n个用空格隔开的数。代表着每个站点的传送距离
输出:
一个整数,旅途中的最少传送次数
样例输入输出
样例1
输入:
5
3 4 1 1 2
输出:
2
#include<iostream>
#include<set>
using namespace std;
/** 样例1
* 输入:
* 5
* 3 4 1 1 2
* 输出:
* 2
*/
int times = 0; // 记录迭代次数
set<int> st; // 记录最小次数
void dongtai(int n, int* a)
{
// 从最后一个倒推到第一个,往前倒推,第1个和第4个可以到达(从0计数),即将他们传进dongtai()函数进行迭代
for (int i = n - 1; i >= 0; i--)
{
if (a[i] + i >= n) // 即若在第i个门可以直接到达终点,即进入迭代
{
times++;
/*for (int k = 0; k < times; k++)
cout << "…";
cout << i << " 可到 "<< n <<",当前迭代了" << times << "次" << endl;*/
dongtai(i, a);
if (i == 0)
{
st.insert(times);
}
times--;
}
//else
//{
// for (int k = 0; k < times; k++)
// cout << "…";
// cout << "第" << i + 1 << "个门不可以到达,当前迭代了" << times << "次" << endl;
//}
}
}
int main()
{
int n; // 一个整数n。代表着目的地的距离
cin >> n;
int * a = new int[n]; // n个用空格隔开的数。代表着每个站点的传送距离,n个值分别代表从a[0]到a[4] 到a[5]的距离
for (int i = 0; i < n; i++)
{
cin >> a[i];
}
dongtai(n, a);
cout << *st.begin();
}