唐克的新游戏
题目描述
唐克新入手了一款PS333平台的游戏,在游戏中从起点到终点共有n个得分点,编号为1~n,需要使用灵能手套才能获得得分点分数,灵能手套经过充能后只可以使用3次。
游戏最终成绩的计算规则如下:假设通过灵能手套获取了三个不同的编号分别为i,j,k的得分点的分数:ai,aj,ak,最终成绩为3个得分点分数总和先减去所选取三点中编号最小值再减去所选取三点中编号最大值,即ai + aj + ak - min(i,j,k) - max(i,j,k)。请你编写程序帮助唐克获得最好成绩。
注:min(i,j,k)表示i,j,k中的最小值,max(i,j,k)表示i,j,k中的最大值。
输入
第一行包含一个整数t,表示有t组测试数据
每组测试数据包含两行:
第一行包含一个整数n,表示游戏中得分点的数量
第二行包含n个整数,表示从起点到终点n个得分点的分数,第i个得分点的分数为ai。
输出
每组测试数据一行,输出唐克所能够获得的最好成绩。
样例输入
【样例1】
1
6
1 2 2 3 3 3
【样例2】
2
6
19 13 4 27 7 11
8
8 7 6 5 4 3 2 1
【样例3】
1
10
1 2 3 9 9 9 10 10 10 10
样例输出
【样例1】
1
【样例2】
54
17
【样例3】
17
提示
对于20%的数据:1<t≤10,3≤n≤100;
对于60%的数据:1≤t≤20,3≤n≤
对于100%的数据:1≤t≤100,3≤n≤,1≤ai≤
。输入文件的大小不超过10MB.
代码#1
(最近做题思路很乱,这道题竟然打了ST表,虽然也过了,实则没必要)
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll T;
int main(){ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);cin>>T;while(T--){ll n,ans=LONG_MIN;cin>>n;ll max_len=log2(n)+2;vector<vector<ll>>a(n+1,vector<ll>(max_len,0));vector<ll>score(n+1);for(ll i=1;i<=n;i++){cin>>score[i];a[i][0]=score[i]-i;}for(ll j=1;(1<<j)<=n;j++){for(ll i=1;i+(1<<j)-1<=n;i++){a[i][j]=max(a[i][j-1],a[i+(1<<(j-1))][j-1]);}}for(ll i=2;i<n;i++){ll l=1,r=i-1;ll x=floor(log2(r-l+1));ll d=max(a[l][x],a[r-(1<<x)+1][x]);l=i+1;r=n;x=floor(log2(r-l+1));ll t=max(a[l][x],a[r-(1<<x)+1][x]);if(ans<d+t+score[i]){ans=d+t+score[i];}}cout<<ans<<"\n";}return 0;
}
代码#2
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll T;
int main(){ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);cin>>T;while(T--){ll n,ans=LONG_MIN;cin>>n;ll max_len=log2(n)+2;vector<ll>score(n+1);vector<ll>max_left(n+1,LONG_MIN);vector<ll>max_right(n+2,LONG_MIN);for(ll i=1;i<=n;i++){cin>>score[i];max_left[i]=max(score[i]-i,max_left[i-1]);}for(ll i=n;i>=1;i--){max_right[i]=max(score[i]-i,max_right[i+1]);}for(ll i=2;i<n;i++){if(ans<max_left[i-1]+max_right[i+1]+score[i]){ans=max_left[i-1]+max_right[i+1]+score[i];}}cout<<ans<<"\n";}return 0;
}