zoukankan      html  css  js  c++  java
  • CF1155D Beautiful Array 贪心,dp

    CF115DBeautiful Array

      题目大意:给一个有n个元素的a数组,可以选择其中一个区间的所有数都乘上x,也可以不选,求最大子序列和。

      如果没有前面的操作,就是只求最大子序列和,我们都知道就一个贪心的思路,当目前序列的和<0了,我们就当它为0,因为它对后面的序列只有负的贡献,完全不会使和增大,只会使和减少。所以我们从左往右,和从右往左,分别处理出没有乘x的最大子序列和maxl和maxr,这样的话,如果我们在区间[l,r]内乘x,那么相应的答案就是(sum[r]-sum[l-1])*x+maxr[r+1]+maxl[l-1],emmm那天晚上我就推到了这,后面怎么枚举区间就不懂了,写了个尺取,但很明显不对,因为没有根据去调整区间。看了我们qdcxk的博客后领悟,还是一种贪心的思想。我们把前面的答案转化成sum[r]*x+maxr[r+1]-(sum[l-1]*x-maxl[l-1]),这样的话

     1 #include<cstdio>
     2 #include<algorithm>
     3 using namespace std;
     4 typedef long long ll;
     5 int a[301108];
     6 ll sum[301108],maxl[301108],maxr[301108];
     7 int main()
     8 {
     9     int n,x,y;
    10     scanf("%d%d",&n,&x);
    11     for(int i=1;i<=n;i++)
    12     {
    13         scanf("%d",&a[i]);
    14         sum[i]=sum[i-1]+a[i];
    15     }
    16     for(int i=1;i<=n;i++)
    17     {
    18         maxl[i]=maxl[i-1]+a[i];
    19         if(maxl[i]<0)
    20             maxl[i]=0;
    21     }
    22     for(int i=n;i>=1;i--)
    23     {
    24         maxr[i]=maxr[i+1]+a[i];
    25         if(maxr[i]<0)
    26             maxr[i]=0;
    27     }
    28     ll ans=0,minl=0;
    29     for(int i=1;i<=n;i++)
    30     {
    31         minl=min(minl,sum[i]*1ll*x-maxl[i]);//先更新minl,就把不选的情况也包含了 
    32         ans=max(ans,maxr[i+1]+sum[i]*1ll*x-minl);
    33     }
    34     printf("%lld
    ",ans);
    35     return 0;
    36 }
    我全都要

    qdcxk还有个dp的做法,先挂上一发k神博客mmk27没看懂等k神给我讲明白了再更。

  • 相关阅读:
    [day002]剑指 Offer 09. 用两个栈实现队列
    [day003]718. 最长重复子数组
    [linux]关于Ubuntu中Could not get lock /var/lib/dpkg/lock解决方案
    96. 不同的二叉搜索树
    91. 解码方法
    [动态规划]64. 最小路径和
    62.不同路径
    【Java】list根据某一条件进行分组
    【Java】批量生成小程序参数码并打包下载
    【Docker】使用docker制作libreoffice镜像并解决中文乱码问题
  • 原文地址:https://www.cnblogs.com/LMCC1108/p/10761228.html
Copyright © 2011-2022 走看看