上机课摸鱼:Lab4-动态规划-星际穿越

文章描述了一个关于宇宙旅行的故事,主人公小南需要通过有限距离限制的任意门到达目标星球。问题转化为寻找最少的传送次数。文中提出了动态规划的解决方法,通过从后往前遍历每个门,判断是否能直达目标并进行递归计算。最终,程序会找到并输出最少的传送次数。
摘要由CSDN通过智能技术生成

题目描述

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();
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值