• Codeforces Round #508 (Div. 2) D. Slime 枚舉


    time limit per test
    2 seconds
    memory limit per test
    256 megabytes

    There are n slimes in a row. Each slime has an integer value (possibly negative or zero) associated with it.

    Any slime can eat its adjacent slime (the closest slime to its left or to its right, assuming that this slime exists).

    When a slime with a value x eats a slime with a value y, the eaten slime disappears, and the value of the remaining slime changes to x−y.

    The slimes will eat each other until there is only one slime left.

    Find the maximum possible value of the last slime.

    Input

    The first line of the input contains an integer n (1n500000) denoting the number of slimes.

    The next line contains nn integers ai (109ai109−109≤ai≤109), where ai is the value of i-th slime.

    Output

    Print an only integer — the maximum possible value of the last slime.

    Examples

    input

    4
    2 1 2 1

    output

    4

    input

    5
    0 -1 -1 -1 -1

    output

    4

    本題大意:
      給定一個數組,每次操作可以讓其中任意的一個數x,吞併他的相鄰的一個數y。吞併后,被吞的數消失,x的值變成x-y,重複此操作直到剩下一個數,求剩下的數的可能的最大值。

    解題思路:
      其實可以分為三種情況討論
      1、給的數組中既有正數也有負數,那麼就總能讓負數吞正數,得到一個絕對值更大的負數,並且吞併后的絕對值是它們的絕對值的和,例如-x吞併y,就的到-x-y = -(x+y),直到剩下一個正數時,讓那個正數把所有的負數吞掉,最後的值,就是所有數的絕對值的和
      2、如果只有正數(負數),那麼就從這些數中選出一對相鄰的數,進行操作,就能得到一個負數(正數)。就有正有負,進入了第一種情形。
      3、特判只有一個數的情形,直接輸出那個數。

      但這裡遇到的問題是,在第二種情況中要先選哪一對相鄰的數,才能得到最優的結果呢?
      我用了很複雜的方法來各種判斷,遍歷很多遍,走了彎路,一直在wa,後來想明白之後覺得自己傻逼了,其實只要遍歷一次把每一對都枚舉一遍記錄最大值就行了。
    所以這裡得到一個啟發,當需要找一個滿足條件值,而限制條件很複雜的時候,應該注意一下複雜度,看是否可以枚舉,枚舉就不需要進行各種特殊的判斷了!

    下面是AC代碼
    #include<bits/stdc++.h>
    #define N 500009
    #define INF 0x3f3f3f3f
    using namespace std;
    typedef long long ll;
    ll a[N],ma[N];
    int main()
    {
        int n;
        int po=0,ne=0;  //正數的個數,負數的個數
        scanf("%d",&n);
        ll sum=0;       //所有數的絕對值的和
        for(int i=1;i<=n;i++)
        {
            scanf("%lld",&a[i]);
            sum+=abs(a[i]);
            if(a[i]>=0)
                po++;
            else
                ne++;
        }
    
        if(n==1)         //特判只有一個數的情況
            printf("%lld
    ",a[1]);
        else
        {
            ll ans=0;
            if(ne&&po)   //如果正數、負數都有,結果就是他們的絕對值的和
                for(int i=1;i<=n;i++)
                    ans+=abs(a[i]);
    
            else         //如果只有正數(負數),先找一對來操作
                for(int i=2;i<=n;i++)
                    ans=max(ans,sum-abs(a[i])-abs(a[i-1])+abs(a[i]-a[i-1]));
            printf("%lld
    ",ans);
        }
    }
     
  • 相关阅读:
    AxWindowsMediaPlayer的详细用法
    C# 播放器控件的常用方法
    在 C# 中使用文件名启动应用程序
    备份和恢复Android手机的NAND分区
    刷Recovery的方法
    WPF RadioButton的探究,为啥选中一个其他都自动不选中了呢?
    WPF大牛Josh Smith 转投 iOS 的怀抱
    终端服务的剪贴板的缺陷,导致WPF调用Clipboard.SetText() 失败
    用df命令查看分区情况
    WPF与输入法冲突研究之二:TextInput事件的BUG?
  • 原文地址:https://www.cnblogs.com/Lin88/p/9605411.html
Copyright © 2020-2023  润新知