失落的圣诞节
Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others)
在樱满集(Ouma Shuu, 简称集)成功阻止修一郎博士,救出楪祈(Yuzuriha Inori, 简称祈)之后,由于默示录病毒的爆发,天王州环状七号线内被封锁,
集所在的学校也在此之内。封锁很快变成了清扫,为了打败政府的幽灵部队,逃出封锁区域,集在学校建立了void
王国。
每个学生都有自己专属的void
,每种专属void
都有对应的属性值,集能将各个学生专属的void
取出来,并交给他们使用。普通学生不能使用别人
的void
,但是作为主角的集和祈能使用任意学生的void
,显然,如果集或者祈使用了某种void
,那么该void
的主人就不能再使用了。当void
在
集或者祈手中,void
的属性值会有所改变,并且集和祈能同时使用同一个学生的void
,且使用相同void
的时候,还会有额外加成的属性值(这就
是传说中爱的力量?)
为了打倒幽灵部队,集决定派出
3
个人,他自己,祈和一个普通学生(精英战术!)。现在希望你帮助集求出,他们
3
个人使用的void
的属性值的
和能达到的最大值。
Input
首先输入一个 t ,表示输入数据组数,对于每组数据。
第一行为一个整数
n
,表示拥有void
的人数。(
3≤n≤10000
,所有属性值小于
2000
)
第二行为
n
个正整数,每个整数表示该种void
的主人用它时的属性值。
第三行为
n
个正整数,每个整数表示该种void
被集使用时的属性值。
第四行为
n
个正整数,每个整数表示该种void
被祈使用时的属性值。
第五行为
n
个正整数,每个整数表示该种void
被集和祈同时使用时的属性加成值。
Output
每组数据输出一行。输出满足题目要求的最大属性值。
Sample input and output
Sample Input | Sample Output |
---|---|
1 4 200 300 400 200 150 200 450 400 100 300 700 500 100 100 100 100 | 1550 |
Hint
在正常情况下,同一种void
不能被多个人使用,唯一的特例情况是题面中所说的集和祈同时使用的时候。
样例解释:
- 普通学生使用第二种
void
,属性值为 300 - 集使用第三种
void
,属性值为 450 - 祈使用第三种
void
,属性值为 700
属性加成为 100
My Solution
#include <cstdio>
#include <algorithm>
//#define LOCAL
using namespace std;
const int maxn=10000+8;
int N[maxn],S[maxn],Q[maxn],Sha,sum[maxn];
int main()
{
#ifdef LOCAL
freopen("a.txt","r",stdin);
#endif // LOCAK
int T,n,maxN,mni,mni2,maxN3,mni3, maxSQ,mqsi, maxs, maxq;
scanf("%d",&T);
while(T--){
maxN=0;maxSQ=0;
scanf("%d",&n);
for(int i=0;i<n;i++)
{scanf("%d",&N[i]);if(maxN<N[i]) {maxN=N[i];mni=i;} }
for(int i=0;i<n;i++)
scanf("%d",&S[i]);
for(int i=0;i<n;i++)
scanf("%d",&Q[i]);
for(int i=0;i<n;i++)
{scanf("%d",&Sha);sum[i]=Sha+S[i]+Q[i];if(maxSQ<sum[i]) {maxSQ=sum[i];mqsi=i;} }
int max1=0,max2=0,max3=0, maxSQ2=0,maxN2=0;
if(mni!=mqsi) max3=maxSQ+maxN;
else{
for(int i=0;i<n;i++)
if(i!=mqsi) maxSQ2=max(maxSQ2,sum[i]);
max1=maxN+maxSQ2; //max0
for(int i=0;i<n;i++)
if(i!=mni) if(maxN2<N[i]) {maxN2=N[i];mni2=i;}
max2=maxN2+maxSQ;
max3=max(max1,max2);
}
int max4=0,max5=0,max6=0;
maxs=0;maxq=0;
for(int i=0;i<mni;i++){
maxq=max(maxq,Q[i]);
maxs=max(maxs,S[i]);
}
for(int i=mni+1;i<n;i++){
maxq=max(maxq,Q[i]);
maxs=max(maxs,S[i]);
}
max4=maxq+maxs+maxN;
maxq=0;maxs=0;
for(int i=0;i<mni2;i++){
maxq=max(maxq,Q[i]);
maxs=max(maxs,S[i]);
}
for(int i=mni2+1;i<n;i++){
maxq=max(maxq,Q[i]);
maxs=max(maxs,S[i]);
}
max5=maxq+maxs+maxN2;
maxN3=0;
for(int i=0;i<n;i++)
if(i!=mni&&i!=mni2) if(maxN3<N[i]) {maxN3=N[i];mni3=i;}
maxq=0;maxs=0;
for(int i=0;i<mni3;i++){
maxq=max(maxq,Q[i]);
maxs=max(maxs,S[i]);
}
for(int i=mni3+1;i<n;i++){
maxq=max(maxq,Q[i]);
maxs=max(maxs,S[i]);
}
max6=maxq+maxs+maxN3;
printf("%d",max(max3,max(max4,max(max5,max6))));
if(T) printf("\n");
}
return 0;
}
没有用线段树,这里有3个要扫描的数组,再用数组建树,加上函数相对for(;;)的时间开销,时间复杂度差不多了,可能还会慢一点。