UVa 1442:Cav(杂题)

来源:互联网 发布:泰国q10牛奶洗面奶知乎 编辑:程序博客网 时间:2024/05/18 03:37

题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=844&page=show_problem&problem=4188

题意:一个洞穴的宽度为n(n106)个片段组成。已知位置[i,i+1]处的地面高度pi和顶的高度si(0pi<si1000),要求在这个洞穴里储存尽量多的燃料,使得在任何位置燃料都不会碰到顶(但是可以无限接近),如图所示。对于该图的例子,最多可以存储21单位的燃料。(本段摘自《算法竞赛入门经典(第2版)》)

洞穴问题示意图

分析:
       可以通过先求“向左延伸不会碰到天花板”的最大值h1(i),再求“向右延伸不会碰到天花板”的最大值h2(i),则hi=min{h1(i),h2(i)}。根据对称性,只考虑h1(i)的计算。
       从左向右扫描。初始时设水位level=s0,然后依次判断各个位置[i,i+1]处的高度。
       如果p[i]>level,说明水被“隔断”了,需要把level提升到pi
       如果s[i]<level,说明水位太高,碰到了天花板,需要把level下降到si
       位置[i,i+1]处的水位就是扫描到位置i时的level。

代码:

#include <fstream>#include <iostream>#include <cstring>#include <algorithm>#include <stack>#include <sstream>#include <string>#include <map>#include <cmath>#include <queue>#include <vector>#include <set>#include <string>#include <vector>using namespace std;const int maxn = 1000000 + 5;int T, n, level, ans;int p[maxn], s[maxn], h1[maxn], h2[maxn];int main(){    scanf("%d", &T);    for (int C = 0; C < T; ++C)    {        ans = 0;        scanf("%d", &n);        for (int i = 0; i < n; ++i)            scanf("%d", &p[i]);        for (int i = 0; i < n; ++i)            scanf("%d", &s[i]);        level = s[0];        for (int i = 0; i < n; ++i)        {            if (level < p[i])                level = p[i];            else if (level > s[i])                level = s[i];            h1[i] = level;        }        level = s[n - 1];        for (int i = n - 1; i >= 0; --i)        {            if (level < p[i])                level = p[i];            else if (level > s[i])                level = s[i];            h2[i] = level;        }        for (int i = 0; i < n; ++i)            ans += min(h1[i], h2[i]) - p[i];        printf("%d\n", ans);    }    return 0;}
0 0
原创粉丝点击