As an owner of a land with a cave you were delighted when you last
heard that underground fuel tanks are great business. Of course, the
more volume one can store, the better. In case of your cave, the
efflective volume is not easy to calculate, because the cave has a
rather sophisticated shape (see figure). Thank heavens it is
degenerate in one dimension!\epsfbox{p4621.eps}
The cave. All ponds that can be flooded with fuel are marked black.
Furthermore, there is some electrical wiring on the ceiling of the
cave. You can never be sure if the insulation is intact, so you want
to keep the fuel level just below the ceiling at every point. You can
pump the fuel to whatever spots in the cave you choose, possibly
creating several ponds. Bear in mind though that the fuel is a liquid,
so it minimises its gravitational energy, e.g., it will run evenly in
every direction on a flat horizontal surface, pour down whenever
possible, obey the rule of communicating vessels, etc. As the cave is
degenerate and you can make the space between the fuel level and the
ceiling arbitrarily small, you actually want to calculate the maximum
possible area of ponds that satisfy aforementioned rules.Input The input contains several test cases. The first line of the
input contains a positive integer Z ≤ 15, denoting the number of
test cases. Then Z test cases follow, each conforming to the format
described belowIn the first line of an input instance, there is an integer n(1 ≤ n ≤ 106) denoting the width of the cave. The second line of
input consists of n integers p1, p2,…, pn and the third line
consists of n integers s1, s2,…, sn, separated by single spaces. The
numbers pi and si satisfy 0 ≤ pi < si ≤ 1000 and denote the
floor and ceiling level at interval [i, i + 1), respectively.Output For each test case, your program has to write an output
conforming to the format described below.Your program is to print out one integer: the maximum total area of
admissible ponds in the cave.
如果想一次确定每个位置的高度的话会很麻烦。当你扫描到一个过低的天花板的时候,不得不倒回去修改原来的值。这样复杂度可能达到O(n^2)。
所以可以扫描两次,第一次只保证液面高度不会超过左边的天花板【具体做法是,维护一个当前液面高度,从左往右扫描,如果当前高度高于天花板,就把高度降到天花板。注意此时并不修改之前的高度,因为这会在第二次扫描时解决。而如果高度低于地板高度,把高度升到地板高度即可。这意思是这里并没有水,此时是不能再往上升的,因为当前是这个高度的原因是向左有这个高度的天花板,如果有水就会淹没。】,第二次只保证高度不超过右边。这两次取min即可。
复杂度可以降到O(n)。
#include<cstdio>
#include<cstring>
int min(int x,int y)
{
return x<y?x:y;
}
int max(int x,int y)
{
return x>y?x:y;
}
int p[1000010],s[1000010],h[1000010];
int main()
{
int i,j,k,l,m,n,q,x,y,z,T,tot,ans,cnt,cur;
scanf("%d",&T);
while (T--)
{
scanf("%d",&n);
for (i=1;i<=n;i++)
scanf("%d",&p[i]);
for (i=1;i<=n;i++)
scanf("%d",&s[i]);
cur=s[1];
for (i=1;i<=n;i++)
{
cur=max(cur,p[i]);
cur=min(cur,s[i]);
h[i]=cur;
}
cur=s[n];
for (i=n;i>=1;i--)
{
cur=max(cur,p[i]);
cur=min(cur,s[i]);
h[i]=min(h[i],cur);
}
ans=0;
for (i=1;i<=n;i++)
ans+=h[i]-p[i];
printf("%d\n",ans);
}
}