【洛谷】P1052 过河

P1052 过河

题目描述

在河上有一座独木桥,一只青蛙想沿着独木桥从河的一侧跳到另一侧。在桥上有一些石子,青蛙很讨厌踩在这些石子上。由于桥的长度和青蛙一次跳过的距离都是正整数,我们可以把独木桥上青蛙可能到达的点看成数轴上的一串整点:0,1,…,L0,1,,L(其中LL是桥的长度)。坐标为00的点表示桥的起点,坐标为LL的点表示桥的终点。青蛙从桥的起点开始,不停的向终点方向跳跃。一次跳跃的距离是SS到TT之间的任意正整数(包括S,TS,T)。当青蛙跳到或跳过坐标为LL的点时,就算青蛙已经跳出了独木桥。

题目给出独木桥的长度LL,青蛙跳跃的距离范围S,TS,T,桥上石子的位置。你的任务是确定青蛙要想过河,最少需要踩到的石子数。

输入输出格式

输入格式:

第一行有11个正整数L(1 \le L \le 10^9)L(1L109),表示独木桥的长度。

第二行有33个正整数S,T,MS,T,M,分别表示青蛙一次跳跃的最小距离,最大距离及桥上石子的个数,其中1 \le S \le T \le 101ST10,1 \le M \le 1001M100。

第三行有MM个不同的正整数分别表示这MM个石子在数轴上的位置(数据保证桥的起点和终点处没有石子)。所有相邻的整数之间用一个空格隔开。

输出格式:

一个整数,表示青蛙过河最少需要踩到的石子数。

输入输出样例

输入样例#1:  复制
10
2 3 5
2 3 5 6 7
输出样例#1:  复制
2

说明

对于30%的数据,L \le 10000L10000;

扫描二维码关注公众号,回复: 2998977 查看本文章

对于全部的数据,L \le 10^9L109。

2005提高组第二题

一开始被题目坑惨了啊...看到题就打了个建边$Spfa$,然后样例怎么过不了???

仔细研读样例发现是在可以不踩石头的情况下最少要踩几个石头啊!!!

然后重新定义dp方程...发现$S$和$T$是小于等于10的,$L$又莽大。所以考虑如何把空间压下去。考虑路径压缩。

以下贴的洛谷大佬Panda_hu的题解:

当然,我觉得还是直接$mod$2520比较好理解...因为在10范围内,不论怎么跳,都可以跳到2520,所以只要两个石头距离大于2520的时候,直接$mod$2520。

路径压缩了过后扫一遍更新即可,如果当前有石头就必须踩。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstring>
using namespace std;

int L, S, T, M, f[3000005], flag[3000005], d[105];

struct Node {
    int pos;
} Stone[105];
bool cmp ( Node a, Node b ) { return a.pos < b.pos; }

int main ( ) {
    scanf ( "%d", &L );
    scanf ( "%d%d%d", &S, &T, &M );
    for ( int i = 1; i <= M; i ++ )
        scanf ( "%d", &Stone[i].pos );
    sort ( Stone + 1, Stone + 1 + M, cmp );
    for ( int i = 1; i <= M; i ++ )
        d[i] = ( Stone[i].pos - Stone[i-1].pos ) % 2520;
    for ( int i = 1; i <= M; i ++ ) {
        Stone[i].pos = Stone[i-1].pos + d[i];
        flag[Stone[i].pos] = 1;
    }
    memset ( f, 0x3f3f3f3f, sizeof ( f ) );
    f[0] = 0;
    for ( int i = 1; i <= Stone[M].pos + T; i ++ ) {
        for ( int j = S; j <= T; j ++ )
            if ( i - j >= 0 ) f[i] = min ( f[i-j], f[i] );
        f[i] += flag[i];
    }
    int ans = 0x3f3f3f3f;
    for ( int i = Stone[M].pos; i < Stone[M].pos + T; i ++ )
        ans = min ( ans, f[i] );
    printf ( "%d", ans );
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/wans-caesar-02111007/p/9570531.html