(模拟/线段树)HDU - 5805 NanoApe Loves Sequence

原题链接:

http://acm.hdu.edu.cn/showproblem.php?pid=5805


题意:

给你一个数列,删除其中的一个数,假设删除任意一个数的概率相同,求相邻的数差的绝对值的最大值的期望,题目只要求输出乘概率前的答案。


分析:

模拟:
只需要先求出本身所有相邻数之差的绝对值,找到最大的那个值和它的位置,然后看删除每一个数对他的影响,所有的最大值加起来就行了。
由于每次删除一个数总会失去两种相邻差值绝对值,并获得一种新的相邻差值绝对值,所以影响只有两种情况:
1、删除的数正好在原数列最大值的位置上,那么最大值将改变,在这里可以直接再跑一边for循环找出最大的,因为也只会出现1-2次,所以对整体复杂度没影响,再把新的最大值和新得到的相邻差值绝对值比较一下,就能得出本次最大值。
2、删除的数不在原数列最大值的位置上,这时只需要把原数列的最大值和新得到的相邻差值绝对值比较一下,就能得出最大值。
注:首尾特殊考虑。

线段树:
有个同学写线段树过了,线段树很更加粗暴,对所有差绝对值建一个线段树,每次删除一个就把要失去的两个相邻差值绝对值都变成新得到的相邻差值绝对值,查询完之后再补回来。。首尾同样特殊处理。。虽然跑的慢些,但还是很屌的。- =0=-
线段树代码链接:http://www.cnblogs.com/s1124yy/p/5745028.html


代码:

  1 #include <iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<vector>
  5 #include<set>
  6 #include<map>
  7 #include<algorithm>
  8 #include<string>
  9 #include<queue>
 10 #include<cmath>
 11 #include<stack>
 12 #include<cctype>
 13 #include<list>
 14 
 15 
 16 #define ll long long
 17 #define ull unsigned long long
 18 
 19 using namespace std;
 20 
 21 const int maxn=100010;
 22 const int inf=1<<30;
 23 
 24 ll num[maxn];
 25 ll cha[maxn];
 26 
 27 int main()
 28 {
 29     //#define DEBUG
 30 
 31 #ifdef DEBUG
 32     freopen("in.txt","r",stdin);
 33     //freopen("out.txt","w",stdout);
 34 #endif
 35 
 36     int t;
 37     scanf("%d",&t);
 38     while(t--){
 39         int n;
 40         scanf("%d",&n);
 41         for(int i=0;i<n;i++){
 42             scanf("%I64d",&num[i]);
 43         }
 44         ll maxs=-1;
 45         int maxi;
 46         for(int i=0;i<n-1;i++){
 47             cha[i]=abs(num[i]-num[i+1]);
 48             if(maxs<cha[i]){
 49                 maxs=cha[i];
 50                 maxi=i;
 51             }
 52         }
 53         //printf("i=%d\n",maxi);
 54         ll ans=0;
 55         for(int i=0;i<n;i++){
 56             if(i==0){
 57                 if(maxi!=i){
 58                     ans+=maxs;
 59                 }
 60                 else{
 61                     ll tmp=-1;
 62                     for(int j=1;j<n-1;j++){
 63                         tmp=max(tmp,cha[j]);
 64                     }
 65                     ans+=tmp;
 66                 }
 67             }
 68             else if(i==n-1){
 69                 if(maxi+1!=i){
 70                     ans+=maxs;
 71                 }
 72                 else{
 73                     ll tmp=-1;
 74                     for(int j=0;j<n-2;j++){
 75                         tmp=max(tmp,cha[j]);
 76                     }
 77                     ans+=tmp;
 78                 }
 79             }
 80             else{
 81                 if(maxi==i||maxi+1==i){
 82                    ll tmp=-1;
 83                    for(int j=0;j<n-1;j++){
 84                         if(j==i-1||j==i)continue;
 85                         tmp=max(tmp,cha[j]);
 86                    }
 87                    tmp=max(tmp,abs(num[i+1]-num[i-1]));
 88                    ans+=tmp;
 89                 }
 90                 else{
 91                     ans+=max(maxs,abs(num[i+1]-num[i-1]));
 92                 }
 93             }
 94             //printf("ans=%I64d\n",ans);
 95         }
 96         printf("%I64d\n",ans);
 97 
 98     }
 99 
100     return 0;
101 }

 

 
posted @ 2016-08-06 23:01  tak_fate  阅读(205)  评论(0编辑  收藏  举报