UESTC 764 失落的圣诞节 直接or线段树orRMQ
失落的圣诞节
Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others)
Submit Status在樱满集(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
| 1 4 200 300 400 200 150 200 450 400 100 300 700 500 100 100 100 100 | 1550 |
Hint
在正常情况下,同一种void不能被多个人使用,唯一的特例情况是题面中所说的集和祈同时使用的时候。
样例解释:
属性加成为 100
My Solution
首先是有组合void的,分成2类 1、maxN + maxSQ ; 2、1)maxN2 + maxSQ ;2)maxN + maxSQ2然后没有组合void的,分成3类 1、maxN + 这个时候对应位置为mni 然后在它的两边分别扫描S、Q 可以得 max4 2、maxN2 + 这个时候对应位置为mni2 然后在它的两边分别扫描S、Q 可以得 max5 3、maxN3 + 这个时候对应位置为mni3 然后在它的两边分别扫描S、Q 可以得 max6 //因为可能N的第1大和第2大位置都被占了,且集和祈的效果更好
具体请看下面,虽然Length挺长的,但Time还是做过那个题目目前为止最快的,Memory也尽可能小了,别人懒得优化这个题目吧
#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 LOCALfreopen("a.txt","r",stdin);#endif // LOCAKint 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; //max0for(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(;;)的时间开销,时间复杂度差不多了,可能还会慢一点。 并且用for可以轻松的S、Q一起扫, 所以在这里就直接搞了。
谢谢
总结
以上是生活随笔为你收集整理的UESTC 764 失落的圣诞节 直接or线段树orRMQ的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: 攻防世界MISC新手题第一题第三题
- 下一篇: 【中钞区块链技术研究院推出区块链小程序应