有n个人参加编程比赛,比赛结束后每个人都得到一个分数;现在所有人排成一圈(第一个和第n个相邻)领取奖品,要求:
1、如果某个人的分数比左右的人高,那么奖品数量也要比左右的人多;
2、每个人至少得到一个奖品;
问最少应该准备多少个奖品。
输入格式
第一行是整数T,表示测试样例个数。
每个测试样例的第一行是一个整数n,表示参加比赛的人数。
第二行是n个正整数a[i],表示从第1个人到第n个人的分数。
输出格式
对每个测试样例,输出应该准备的最少奖品,每个结果占一行。
数据范围
1≤T≤101≤T≤10,
0<n<1000000<n<100000,
#include <iostream>
#include <algorithm>
using namespace std;
const int N=100010;//segmentation fault,开的空间小了起初10010
typedef pair<int,int> PII;//pair类似Python字典,排序之后保存原先的下标。
typedef long long LL;
PII children[N];
int bonus[N],a[N];
int main(){
int T;
cin>>T;
while(T--){
int n;
cin>>n;
for(int i=0;i<n;i++){
cin>>a[i];
children[i]={a[i],i};
}
LL res=0;
sort(children,children+n);//对pair进行排序
for(int i=0;i<n;i++){
int left = (children[i].second+n-1)%n, right = (children[i].second+1)%n;
int lv=1,rv=1;//定义int的时候可以计算值,特殊的环形求左右的方式,(+n)%n
// if(children[i].first>children[left].first) lv=bonus[left]+1;children[left]值已经变化;
if(children[i].first>a[left]) lv=bonus[left]+1;//如果比这个当前数据的左边大,+1
if(children[i].first>a[right]) rv=bonus[right]+1;
bonus[children[i].second]=max(lv,rv);//对原先的位置的数据应该放多少处理
// cout<<'['<<i<<']'<<bonus[i]<<' '<<left<<' '<<right<<' '<<children[i].first<<' '<<children[i].second<<endl;
}
for(int i=0;i<n;i++){
res+=bonus[i];
}
cout<<res<<endl;
}
return 0;
}
0<a[i]<1000000<a[i]<100000
输入样例:
2
2
1 2
4
1 2 3 3
输出样例:
3
8
https://www.acwing.com/problem/content/681/,,https://www.bilibili.com/video/av49335912老师讲解视频