• HDU 5805 NanoApe Loves Sequence (思维题) BestCoder Round #86 1002


    题目:传送门

    题意:题目说的是求期望,其实翻译过来意思就是:一个长度为 n 的数列(n>=3),按顺序删除其中每一个数,每次删除都是建立在最原始数列的基础上进行的,算出每次操作后得到的新数列的相邻两数的差的绝对值的最大值,求这些n个最大值的总和。

    题解:把n=3的情况单独拿出来直接算出来,就是abs(data[3]-data[2])+abs(data[2]-data[1])+abs(data[3]-data[1]),然后讨论n>=4的情况。首先遍历求出原始数列的相邻两数的差的绝对值的最大值mx,设这两个相邻的数的下标为mi-1mi,我们在本题中以右边mi基准。然后依次考虑删除mi-1mi这两个点的时候的情况,也就是说求出没有mi-1这个点的时候得到的最大值,再求出没有mi这个点的时候得到的最大值,设他俩分别为mx2mx3,用if continue就可以实现,就是循环到那个点的时候跳过两次就行了,为什么要跳过两次呢?因为删去一个点会影响到他右边这两个数作为基准求最大值的情况,两边所以要跳过两次。这样数据就够用了可以求答案了。

    随后考虑把两端的点删除的时候的最大值,不一定是mx+mx,如果mi-1==1或者mi==n要单独考虑初始值,用if判断一下即可,比如 1 7 100 6这组数据就是mi==n的情况,答案是94+99+6+93=292,初始值是94+93=187,也就是mx+mx3,在纸上写一下就很容易明白了。随后进行遍历即可,遍历过程就是考虑在2n-1这些数中依次删去每个数看abs(data[i+1]-data[i-1])是否比现有的最大值还要大,取其中较大值加到ans里即可,但是不要更新最大值,因为那样是不对的,另外注意这里的最大值不是同一个,对于非mimi-1这两个点的点来说最大值是mx,对于mi-1来说最大值是mx2,对于mi来说最大值是mx3。具体过程请看代码,如果有没看懂的或者更好的解决办法欢迎大家留言给我。

    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <cstdlib>
    #include <iostream>
    using namespace std;
    const int maxn=1e5+5;
    typedef long long ll;
    ll data[maxn];
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            int n;
            scanf("%d",&n);
            ll mx=-1,mi=-1,tmp;
            memset(data,-1,sizeof(data));
            for(int i=1; i<=n; i++)
                scanf("%lld",&data[i]);
            ll ans=0;
            if(n==3)
            {
    //            cout<<abs(data[3]-data[2])<<endl;
    //            cout<<abs(data[3]-data[1])<<endl;
    //            cout<<abs(data[2]-data[1])<<endl;
                ans=ans+abs(data[3]-data[2])+abs(data[2]-data[1])+abs(data[3]-data[1]);
                printf("%lld
    ",ans);
                continue;
            }
            for(int i=2; i<=n; i++)
            {
                tmp=abs(data[i]-data[i-1]);
                if(tmp>mx)
                {
                    mx=tmp;
                    mi=i;
                }
            }
            ll mx2=-1,m2i=-1;
            for(int i=2; i<=n; i++)
            {
                if(i==mi-1||i==mi) continue;
                tmp=abs(data[i]-data[i-1]);
                if(tmp>mx2)
                {
                    mx2=tmp;
                    m2i=i;
                }
            }
            ll mx3=-1,m3i=-1;
            for(int i=2; i<=n; i++)
            {
                if(i==mi+1||i==mi) continue;
                tmp=abs(data[i]-data[i-1]);
                if(tmp>mx3)
                {
                    mx3=tmp;
                    m3i=i;
                }
            }
            //cout<<mx2<<endl<<mx3<<endl;
            if(mi==n)
            ans=mx+mx3;
            else if(mi==2)
            ans=mx+mx2;
            else
            ans=mx+mx;
            //cout<<ans<<endl;
            for(int i=2; i<=n-1; i++)
            {
                if(i==mi-1)//代表mi-1和mi
                {
                    tmp=abs(data[i+1]-data[i-1]);
                    if(tmp>mx2)
                        ans+=tmp;
                    else
                        ans+=mx2;
                }
                else if(i==mi) //代表mi和mi+1
                {
                    tmp=abs(data[i+1]-data[i-1]);
                    if(tmp>mx3)
                        ans+=tmp;
                    else
                        ans+=mx3;
                }
                else
                {
                    tmp=abs(data[i+1]-data[i-1]);
                    if(tmp>mx)
                        ans+=tmp;
                    else
                        ans+=mx;
                }
            }
            printf("%lld
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    庄家试盘的K线形态
    股票基本知识入门提纲
    我与猫
    夜雨不眠时
    快速排序
    由float转std::string的方法
    BugFree + EasyPHP在Windows平台搭建步骤详解
    安装VS2008的时候Windows Mobile 5.0 SDK R2 for pocket pc错误解决方案
    收集WCF文章
    linq to ef(相当于sql中in的用法)查询语句
  • 原文地址:https://www.cnblogs.com/Ritchie/p/5747121.html
Copyright © 2020-2023  润新知