P1929 迷之阶梯

链接:https://www.luogu.com.cn/problem/P1929
题目:

思路:动态规划:以times[i]表示跳到第i号台阶的最小步数。
如果height[i] == height[i-1] + 1那么显然有times[i] = times[i-1] + 1
然后是遍历的状态转移方程:如果j号位加上2^delta可以跳到i号位,那么更新times[i] = min(times[i],times[delta + j] + delta + 1)这个式子的意思就是从delta + j号位回跳delta步,然后一跃到i。
所以代码如下:

#define _CRT_SECURE_NO_WARNINGS 
#include<iostream>
#include<vector>
#include<algorithm>
#include<math.h>
#include<sstream>
#include<string>
#include<string.h>
#include<iomanip>
#include<stdlib.h>
#include<map>
#include<queue>
#include<limits.h>
#include<climits>
#include<fstream>
#include<stack>
typedef long long ll;
using namespace std;
const int N = 210;
ll height[N];
ll times[N];
int main()
{
	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
	int n; cin >> n;
	for (int i = 1; i <= n; i++)times[i] = -1;
	for (int i = 1; i <= n; i++)cin >> height[i];
	times[1] = 0;
	for (int i = 2; i <= n; i++)
	{
		if (height[i] == height[i - 1] + 1)times[i] = times[i - 1] + 1;
		for (int j = 1; j < i; j++)
		{
			int delta = ceil(log2(height[i] - height[j]));
			if (delta + j < i)
			{
				if (times[i] == -1)
				{
					times[i] = times[delta + j] + delta + 1;
				}
				else times[i] = min(times[i], times[delta + j] + delta + 1);
			}
		}
		if (times[i] == -1)break;
	}
	cout << times[n];
	return 0;
}

posted on 2024-05-26 09:58  WHUStar  阅读(3)  评论(0编辑  收藏  举报