NMS

69 篇文章 0 订阅

NMS


题目描述

某巨魔需要找一个叫 Nimas 的 NPC 完成任务,他来到了某个大湖泊,湖泊上有个湖心岛,Nimas 就在上面。
巨魔无法从湖中游到湖心岛,因为水中会拉到很多怪物,会耗费大量时间。
所幸的是,在湖边有 N 个依次连接到湖心岛的木桩,标号 1 N
对于这个巨魔来说,每个木桩都有个技巧值。巨魔可以很容易地在技巧值低的木桩上站稳,但是对于技巧值高的木桩,巨魔需要很好的微操才能在木桩上站稳脚跟。
巨魔的跳跃方式有一定规律:即如果巨魔在木桩 i 上,那么它下一步只能跳跃到木桩 i+L i+R 中的某个木桩上,巨魔不能往回跳。
现在巨魔在 1 号木桩上,它希望最后它能站在第 N 个木桩上,并且它跳过的木桩的技巧值总和最小 (包括 1 号和 N 号木桩的技巧值) , 如果这个不能实现, 那么就输出 -1(不带引号) 。


输入格式

第一行一个数字 N L R
接下来一行 N 个空格隔开的数字 s[i] ,表示第 i 个木桩的技巧值。


输出格式

输出一行,即最小技巧值总和,如果不存在方案则输出 -1(不带引号) 。


样例输入

5 1 3
1 2 3 4 5


样例输出

8


样例解释

1 号木桩跳到 2 号木桩,从 2 号木桩跳到 5 号木桩,总的技巧值为s[1]+s[2]+s[5]=8


数据范围

30% 的数据: 1LRN1000
100% 的数据: 1LRN106 1s[i]109


Solution

f[i] 表示当前在 i 木桩上的总的最小技巧值。

f[i]=minilj=irf[j]+s[i]

这个方程可以用单调队列进行优化。


Code

#include <iostream>
#include <cstdio>
#include <cstring>

#define Max(x,y) ((x)>(y)?(x):(y))
#define Min(x,y) ((x)<(y)?(x):(y)) 
#define LL long long

using namespace std;

int n,l,r,tail,front;

LL f[1000010],w[1000010],q[1000010][2],oo;

int main(){

    freopen("Nimas.in","r",stdin);
    freopen("Nimas.out","w",stdout);

    memset(f,0x3f,sizeof f);oo=f[0];

    scanf("%d%d%d",&n,&l,&r);
    for(int i=1;i<=n;i++)scanf("%lld",&w[i]);

    f[1]=w[1];
    q[++tail][0]=q[++front][1]=f[1];
    q[tail][1]=q[front][1]=1;

    for(int i=2;i<=n;i++){
        int minx=Max(1,i-r),maxn=i-l;
        if(minx>maxn)continue;
        while(q[tail][1]<minx&&tail<=front)tail++;
        if(i-l>=1){
            while(q[front][0]>f[i-l]&&front>tail){
                --front;
            }
            if(q[front][0]<f[i-l]){
                q[++front][0]=f[i-l];
                q[front][1]=i-l;
            }
            else{
                q[front][0]=f[i-l];
                q[front][1]=i-l;
            }
        }
        f[i]=q[tail][0]+w[i];
    }

    if(f[n]!=oo)printf("%lld\n",f[n]);
    else printf("-1\n");

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值