经典题目:漂流

漂流

题目描述

暑期将至,小鼠 Jack 决定到鼠国最著名的蓝阴河去玩漂流。
我们假定蓝阴河宽度为 m 米,其中每隔一定距离就会有一处障碍(为了
让漂流更刺激~),一共有 n 个障碍,第 i 个障碍的 Xi-Yi 米处是一个开口,只有从障碍中间的开口处才能通过(开口包含 Xi,Yi)。现在 Jack 位于 1 号障碍的开口处,他要划艇依次通过这些障碍,但是 Jack 比较懒,每当他向左或向右移动 1 米,他就会消耗 1 点体力。由于水流的作用,Jack 向前移动不消耗体力。现在,他希望知道,他依次通过这些障碍所需要消耗的最小体力是多少。

思路

贪心?
DP?空间复杂度O(nm),时间复杂度O(nm²)
所以我们能不能采用一些技巧优化DP呢?显然可以。
好吧我们重新引入贪心的思路,提出下面的结论:
最优的方案,一定是从某些障碍的开口边缘处直接游向另一
些障碍的开口边缘处(不一定是相邻的两个障碍,但是一定
能直接游过去)
那么此时的DP方程就很好看了:设f[i][k]表示走到第i个障碍的开
口边缘处需要消耗的最少体力(k=0代表左边缘,1代表右边缘)
f[i][k]=min(f[j][l]+|x[j][l]-x[i][k]|) (j

* 但是*

这明显就是水题啊!!!!

代码

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
const int N=1e5+5;
const int M=1e9+5;
int n,m,zuo[N],you[N],ans=0,pos,now;
int main()
{
    scanf("%d%d",&n,&m);
//  memset(zuo,0,sizeof(zuo));
//  memset(you,0,sizeof(you));
    scanf("%d%d",&zuo[1],&you[1]);
    pos=zuo[1];
    for (int i=2;i<=n;i++)
    {
        scanf("%d%d",&zuo[i],&you[i]);
        if (zuo[i]<=pos&&you[i]>=pos) continue;
        if (abs(pos-zuo[i])>abs(pos-you[i]))
        {
            ans+=abs(pos-you[i]);
            pos=you[i];
        }
        else
        {
            ans+=abs(pos-zuo[i]);
            pos=zuo[i];
        }
    }
    printf("%d",ans);
    return 0;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值