NKOJ 6992 考古
NKOJ 6992 考古
思路:DP
实现方法
-
状态:\(dp_{i}\) 表示走到第 \(i\) 步时,的最小步数。
-
转移:
-
题目中并没有说楼梯必须一级一级地上,所以我们可以对于每一及楼梯,只关心走到它的最小值。
-
于是对于每一级楼梯枚举从哪里开始退和退到哪里。
-
由于退得多时一定不如退得少,所以我们算不出 \(2^{198}\) 的问题不必担心,因为不管进不进入一定没有答案。
-
-
初始值:\(dp_1=0\),其他的赋值为 \(\inf\)
-
遍历顺序:\(i\) 表示我想上到第几级从\(2 \sim n\),\(j\) 表示从哪里开始退从\(i-1 \sim 1\),\(k\) 表示退到哪里,从\(j\sim 1\)。
-
答案:\(dp_n\) 如果是 \(\inf\) 就无解,否则直接输出。
代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
int dp[205],arr[205];
signed main(){
int n;
cin>>n;
for(int i=1;i<=n;i++) cin>>arr[i];
memset(dp,0x3f,sizeof(dp));
dp[1]=0;
for(int i=2;i<=n;i++){
for(int j=i-1;j>=1;j--){//注意点1
for(int k=j;k>=1;k--){
if(arr[i]-arr[k]<=1<<(j-k)){
dp[i]=min(dp[j]+j-k+1,dp[i]);
}
}
}
}
if(dp[n]==0x3f3f3f3f3f3f3f3f) cout<<-1;
else cout<<dp[n];
return 0;
}
注意事项
- 由于还没有到第 \(i\) 级台阶,所以最多从 \(i-1\) 开始退。