您的位置:首页 > 其它

Codechef A temple of Snakes(思维)

2017-05-30 15:21 477 查看
点击打开链接

 题意

你想要为众蛇建造一座神殿。神殿将建在群山之中,可以将其视作n个块,其中第i个的高度为hi。神殿会建造在连续若干个块上,要求这些块的高度从1开始逐渐增加到某个高度,然后再逐渐减小到1,即,高度是形如1,2,3, ... ,x−1,x,x−1,x−2,...,1的序列。除了要建造神殿的块之外,其他块的高度都应该是0,以便人们从左右两侧看到神殿。

为了达成这一目标,你可以降低块的高度。一次操作中,你可以选择一块,并令其高度减小1。请求出最少需要进行多少次操作。

数据

输入的第一行包含一个整数 T,代表测试数据的组数。接下来是 T 组数据。每组数据的第一行包含一个整数n。接下来一行包含n个整数,其中第i个代表hi。

对于每组数据,输出一行,包含一个整数,代表最少需要的操作次数。

1<=T<=10, 2<=n<=1e5, 1<= hi<=1e9

输入

3

3

1 2 1

4

1 1 2 1

5

1 2 6 2 1

输出

0

1

3

说明

在第一组数据中,整座山已经符合要求。

在第二组数据中,将第 1 块的高度减小为 0,便可以在后 3 块上建造神殿。

在第三组数据中,可以将第 3 块的高度减小为 3。


思路(摘自Wannafly Union)

这道题的本质是求我们能留下来的最大的塔有多大,然后用总块数-用掉的块数就可以求出答案。我们考虑以每个点为中心,塔的左边能造多高。假设i号点最高能建h,那么i+1号点最高能建min(h+1,自身高度)。同理可求只考虑右边的情况。最后求个最值就可以了。

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
const int maxn = 1e5+5;
int a[maxn], l[maxn], r[maxn];

int main(void)
{
int t, n;
cin >> t;
while(t--)
{
memset(a, 0, sizeof(a));
memset(l, 0, sizeof(l));
memset(r, 0, sizeof(r));
scanf("%d", &n);
ll sum = 0;
for(int i = 1; i <= n; i++)
scanf("%d", &a[i]), sum += a[i];
for(int i = 1; i <= n; i++)
l[i] = min(a[i], l[i-1]+1);
for(int i = n; i >= 1; i--)
r[i] = min(a[i], r[i+1]+1);
ll ans = 0;
for(int i = 1; i <= n; i++)
ans = max(ans, (ll)min(l[i], r[i]));
printf("%lld\n", sum-(1+ans-1)*(ans-1)-ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: