【递推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)\)
posted @ 2020-09-05 11:17  童年の波鞋  阅读(136)  评论(0编辑  收藏  举报