古老的牛市,遗迹的天梯 (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; }