【CF1706-C】Qpwoeirut And The City

题目链接

英语题面:

Qpwoeirut has taken up architecture and ambitiously decided to remodel his city.

Qpwoeirut's city can be described as a row of n𝑛 buildings, the i𝑖-th (1≤i≤n1≤𝑖≤𝑛) of which is hiℎ𝑖 floors high. You can assume that the height of every floor in this problem is equal. Therefore, building i𝑖 is taller than the building j𝑗 if and only if the number of floors hiℎ𝑖 in building i𝑖 is larger than the number of floors hjℎ𝑗 in building j𝑗.

Building i𝑖 is cool if it is taller than both building i−1𝑖−1 and building i+1𝑖+1 (and both of them exist). Note that neither the 11-st nor the n𝑛-th building can be cool.

To remodel the city, Qpwoeirut needs to maximize the number of cool buildings. To do this, Qpwoeirut can build additional floors on top of any of the buildings to make them taller. Note that he cannot remove already existing floors.

Since building new floors is expensive, Qpwoeirut wants to minimize the number of floors he builds. Find the minimum number of floors Qpwoeirut needs to build in order to maximize the number of cool buildings.

Input

The first line contains a single integer t𝑡 (1≤t≤1041≤𝑡≤104) — the number of test cases.

The first line of each test case contains the single integer n𝑛 (3≤n≤1053≤𝑛≤105) — the number of buildings in Qpwoeirut's city.

The second line of each test case contains n𝑛 integers h1,h2,…,hnℎ1,ℎ2,…,ℎ𝑛 (1≤hi≤1091≤ℎ𝑖≤109) — the number of floors in each of the buildings of the city.

It is guaranteed that the sum of n𝑛 over all test cases does not exceed 2⋅1052⋅105.

Output

For each test case, print a single integer — the minimum number of additional floors Qpwoeirut needs to build in order to maximize the number of cool buildings.

大致题意:
n个建筑物1~n,高度数组hi。高度大于两侧=建筑高于。
cool:比两边的楼高(1和n不行)
最大化cool楼的个数(只能增加h不能减少) 
求最小增加的h并输出。

前缀和

+表示cool,-表示不cool。
n为偶数:
        ans1:-+-+-- 前缀和 遍历下标2到n-1(+=2) ans1[n-2] 
        ans2:--+-+- 前缀和 遍历下标3到n-1(+=2) ans2[n-1] 
                min(ans1[n-2] ,ans2[n-1] )
        ans3:-+- -+- (枚举‘--’所在的位置)
                把'+--'的'+' 记为i ,'--+'的'+'则为 i+3 ,但注意ans2是按‘-+’来算的所以下面是n-1
                (从2到i的)ans1[i] + (从i+2到n-1的)ans2[n-1]-ans2[i+2] min 
n为奇数:-+-+- 枚举,下标2 ~ n-1(+=2) is cool,求和就好。


训练赛补的题,就会一道写完就躺平了,没拿纸笔,分析是在注释里敲的,很意识流。

大样例都过不去破防很久原来是i+=全部写成i++,晕了。

然后发现&1求奇偶也做反了。改完就一遍ac了0.0

AC代码:

#include <bits/stdc++.h>
#define endl '\n'
#define int long long
using namespace std;


void solve()
{
	int n;
	cin>>n;
	vector<int> h(n+1);
	for(int i=1 ; i<=n ; i++)
	{
		cin>>h[i];
	}
	int ans=0;
	if((n&1)==0)//偶
	{
		vector<int> ans1(n+1,0); 
		for(int i=2 ; i<=n-1 ; i+=2)
		{
			int temp1=0,temp2=0;
			if(h[i]<=h[i-1]) temp1=h[i-1]-h[i]+1;
			if(h[i]<=h[i+1]) temp2=h[i+1]-h[i]+1;
			ans1[i]+=max(temp1,temp2);
			if(i!=2) ans1[i]+=ans1[i-2];
		}
		vector<int> ans2(n+1,0);
		for(int i=3 ; i<=n-1 ; i+=2)
		{
			int temp1=0,temp2=0;
			if(h[i]<=h[i-1]) temp1=h[i-1]-h[i]+1;
			if(h[i]<=h[i+1]) temp2=h[i+1]-h[i]+1;
			ans2[i]+=max(temp1,temp2);
			if(i!=3) ans2[i]+=ans2[i-2];
		}
		ans=min(ans1[n-2],ans2[n-1]);
		for(int i=2 ; i<=n-3 ; i+=2)
		{
			int temp3=ans1[i]+ans2[n-1]-ans2[i+1];
			ans=min(ans,temp3);
		}
	}
	else //奇
	{
		ans=0;
		for(int i=2 ; i<=n-1 ; i+=2)
		{
			int temp1=0,temp2=0;
			if(h[i]<=h[i-1]) temp1=h[i-1]-h[i]+1;
			if(h[i]<=h[i+1]) temp2=h[i+1]-h[i]+1;
			ans+=max(temp1,temp2);
		}
	}
	cout<<ans<<endl; 
}


signed main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int t=1;
	cin>>t;
	while(t--)
	solve();
	return 0;
 }

  • 17
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值