我是传送门
Little Dormi received a histogram with n bars of height a1,a2,…,an for Christmas. However, the more he played with his new histogram, the more he realized its imperfections, so today he wanted to modify it to his liking.
To modify the histogram, Little Dormi is able to perform the following operation an arbitrary number of times:
Select an index i (1≤i≤n) where ai>0, and assign ai:=ai−1.
Little Dormi defines the ugliness score of his histogram (after performing some number of operations) as the sum of the vertical length of its outline and the number of operations he performed on it. And to make the histogram as perfect as possible, he would like to minimize the ugliness score after modifying it with some number of operations.
However, as his histogram is very large, Little Dormi is having trouble minimizing the ugliness score, so as Little Dormi’s older brother, help him find the minimal ugliness.
Consider the following example where the histogram has 4 columns of heights 4,8,9,6:
The blue region represents the histogram, and the red lines represent the vertical portion of the outline. Currently, the vertical length of the outline is 4+4+1+3+6=18, so if Little Dormi does not modify the histogram at all, the ugliness would be 18.
However, Little Dormi can apply the operation once on column 2 and twice on column 3, resulting in a histogram with heights 4,7,7,6:
Now, as the total vertical length of the outline (red lines) is 4+3+1+6=14, the ugliness is 14+3=17 dollars. It can be proven that this is optimal.
Input
Each test contains multiple test cases. The first line contains the number of test cases t (1≤t≤104). Description of the test cases follows.
The first line of each test case contains a single integer n (1≤n≤4⋅105).
The second line of each test case contains n integers a1,a2,…,an (0≤ai≤109).
It is guaranteed that the sum of n over all test cases does not exceed 4⋅105.
Output
For each test case output one integer, the minimal ugliness Little Dormi can achieve with the histogram in that test case.
Example
Input
2
4
4 8 9 6
6
2 1 7 4 0 0
Output
17
12
题意:观察柱状图,通过改变蓝色方块的数量,使红色边框达到最小。最后的sum等于红色边框的和加上操作的次数。
分析:如果就删掉一个方块(左右都没有其他方块),操作数加1,边框数减2。大于等于2的删去都不能使sum减少。另外,如果左右都是高的,中间夹杂着一个最矮的,使中间的与左右较矮的平齐,操作数n,边框减少2n;
方法:
1.从左边向右遍历,如果第i个与左边的右边的都不相等,则f[i]减小到f[i+1];
AC代码:
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
using namespace std;
typedef long long ll;
ll a[400010],b[400010];
int main()
{
ll t,ans,n,i;
scanf("%lld",&t);
while(t--)
{
ans=0;
//memset(a,0,sizeof(a));
//memset(b,0,sizeof(b));
scanf("%lld",&n);
for(i=1;i<=n;i++)
scanf("%lld",&a[i]);
a[0]=0;
a[n+1]=0;
for(i=1;i<=n;i++)
{
if((a[i]>a[i-1]&&a[i]>a[i+1]))
b[i]=max(a[i-1],a[i+1]);
else
b[i]=a[i];
ans+=a[i]-b[i]+abs(b[i]-b[i-1]);
}
printf("%lld\n",ans+b[n]);//注意看图下标从0开始的,所以有n+1组数
//memset(a,0,(n+1)*4 );
//memset(b,0,(n+1)*4);
//和上面同理,一个int占4个字节,memset按照字节清空
if(!t)
{
for(i=1;i<=n;i++)
{
a[i]=0;
b[i]=0;//其实只用清空A数组就可以了n
}
}
}
}
注意:memset(b,0,sizeof(b));是一次性清空b[400010],复杂度增加400010,这样写会超时。而memset(a,0,(n+1)*4 );复杂度只增加(n+1)*4,或者用for循环赋值也可。