【递推dp】C001_AW_雪靴(检查后面的d格能否到当前位置)
第 i 双靴子能让John踏入厚度为 s 的积雪,且最多跨d步,求John从1到n号格子最小消耗。第1个和最后一个格子没有积雪
输出格式
输出包含一个整数,为 Farmer John 需要丢弃的靴子的最小双数。
输入保证 Farmer John 能够到达牛棚。
数据范围
2≤N,B≤250,
0≤fi,si≤109,
1≤di≤N−1
输入样例:
10 4
0 2 8 3 6 7 5 1 4 0
2 3
4 2
3 4
7 1
输出样例:
2
方法一:dp
递推...
- 定义状态:
- f[i] 表示走到第i格阶梯需要的靴子数
- 思考初始化:
- f[...]=false, f[1]=true
- 思考状态转移方程:
- f[j]|=f[k],k∈[j-ss[i].d,j],只要在前 ss[i].d 格到底j格范围内,即:j-ss[i].d 个格子到第 j 个格子中有一个能到 j,则 f[j]=true
- 思考输出:i-1,if(f[n])
#include<bits/stdc++.h>
using namespace std;
struct node{
int s,d;
};
int main() {
std::ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int n,b; cin>>n>>b;
int h[n+1], f[n+1]; memset(f,false,sizeof f); for (int i=1; i<=n; i++) cin>>h[i];
node ss[b+1]; for (int i=1; i<=b; i++) cin>>ss[i].s>>ss[i].d;
f[1]=1;
for (int i=1; i<=b; i++) {
for (int r=1; r<=n; r++) if (h[r]<=ss[i].s) {
for (int l=r; l>=0 && l>=r-ss[i].d && !f[r]; l--) if (h[l]<=ss[i].s) //往后走r-ss[i].d步
f[r]|=f[l];
}
if (f[n]) return cout<<i-1, 0;
}
return 0;
}
复杂度分析
- Time:\(O(nb)\),
- Space:\(O(n)\),