经典题目:漂流

来源:互联网 发布:xd查询软件 编辑:程序博客网 时间:2024/04/27 14:19

漂流

题目描述

暑期将至,小鼠 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;} 
原创粉丝点击