古老的牛市,遗迹的天梯 (DP)

思路:,令表示到达第级阶梯的最小步数。

因为题目保证阶梯高度递增,

所以当

然后根据题目还可以由中能够跳的转移过来。

所以我们可以枚举起跳的点.然后转移,注意开始后退的点必须小于等于,因为如果开始后退的点比还大就肯定不是最优的,因为可以直接后退到点

时间复杂度:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=210,inf=0x3f3f3f3f;
#define mst(a) memset(a,0,sizeof a)
#define lx x<<1
#define rx x<<1|1
#define reg register
#define PII pair<int,int>
#define fi first 
#define se second
inline void read(int &x){ 
    x=0;int w=1;
    char ch=getchar();
    while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();}
    for(;ch>='0'&&ch<='9';ch=getchar())
        x=(x<<3)+(x<<1)+(ch&15);
    x*=w; 
}
int dp[N],a[N]; 
int main(){
    int n;
    read(n);
    for(reg int i=1;i<=n;i++) read(a[i]);
    memset(dp,0x3f,sizeof dp);
    dp[1]=0;
    for(reg int i=2;i<=n;i++)
    {
        if(a[i]==a[i-1]+1) dp[i]=min(dp[i],dp[i-1]+1);
        for(reg int j=1;j<i;j++){
            int k=ceil(log2(a[i]-a[j]));
            if(j+k<=i) dp[i]=min(dp[i],dp[j+k]+k+1);
        }
    }
    printf(dp[n]==inf?"-1":"%d\n",dp[n]);
    return 0;
}