zoukankan      html  css  js  c++  java
  • CF1038D Slime(思维+枚举+贪心)(来自洛谷)

    洛谷地址:https://www.luogu.com.cn/problem/CF1038D

    题意:

    n只史莱姆,每一个史莱姆可以吃相邻的左或右,它的分数就变成:它的分数-被吃的分数

    求最大的剩余值。

    解析:

    如果对过程进行太多的分析的话,问题就会变得很复杂。刚开始想的是,把所有能算出来的负数弄出来,但是情况又有好多,接着又想到dp....越想越多。

    这个时候,尝试分情况讨论,简化具体过程,这是一个教训!

    1:正负均有,要想结果最大,肯定是让负数尽可能多,然后让正数去减它。

    假设有x个正数,让负数把x-1的正数全变成负数,让最后的那个正数去减所有负数,得到的结果就是所有数的绝对值之和。

    既然正负均有,那么肯定存在正负相邻,所以这个结论是正确的。

    2:全为正

    参照一,如果弄出一个负数来,那么结果也跟绝对值有关,就是:去掉它俩的剩余数的绝对值之和+它俩吃出的价值(取正,因为吃左吃右都可以)

    这个时候就可以O(N)枚举相邻数了。

    全为负同理。

    #include<bits/stdc++.h>
    #include<iostream>
    #include<cstring>
    #include<string.h>
    #include<cmath>
    #include<map>
    using namespace std;
    typedef long long ll;
    const int maxn=5e5+10;
    ll a[maxn];
    ll b[maxn];
    int vis[maxn];
    int main()
    {
        int n;
        cin>>n;
        int tot=0;
        int z=0,f=0;
        ll sum=0;
        for(int i=1;i<=n;i++)
        {
            cin>>a[i];
            sum+=abs(a[i]);
            if(a[i]>0)
                z++;
            if(a[i]<0)
                f++;
        }
        if(n==1)
            cout<<a[1]<<endl;
        else if(z>0&&f>0)
        {
            cout<<sum<<endl;
        }
        else
        {
            ll ans=0;
            for(int i=2;i<=n;i++)
            {
                ans=max(ans,sum-abs(a[i])-abs(a[i-1])+abs(a[i]-a[i-1]));
            }
            cout<<ans<<endl;
        }
    }
  • 相关阅读:
    硬件加速器为人工智能应用服务
    js 获取指定字符串个数
    js 仿微信投诉—引入vue.js,拆分组件为单个js
    css 图片波浪效果
    svg path命令
    谷歌浏览器—打断点调试页面
    js 实现加载百分比效果
    js 实现纵向轮播
    css 图片高度自适应
    js 禁止/允许页面滚动
  • 原文地址:https://www.cnblogs.com/liyexin/p/13381279.html
Copyright © 2011-2022 走看看