zoukankan      html  css  js  c++  java
  • Educational Codeforces Round 63 (Rated for Div. 2) D. Beautiful Array(动态规划.递推)

    传送门

    题意:

      给你一个包含 n 个元素的序列 a[];

      定义序列 a[] 的 beauty 为序列 a[] 的连续区间的加和最大值,如果全为负数,则 beauty = 0;

      例如:

      a[] = {10, -5, 10, -4, 1} ;

      beauty = 15;( 10+(-5)+10 )

      a[] = {-3, -5, -1};

      beauty = 0;( 不取 )

      给你一个整数 x,你可以将序列 a[] 的任意子序列 a[ l , r ]*x(即 a[l]=a[l]*x,a[l+1]=a[l+1]*x,.....,a[r]=a[r]*x);

      当然,也可以不执行这个操作;

      求 beauty 的最大值;

    思路:

      一看到这道题,第一反应就贪过去了;

      贪了好大一会,交了几发程序,全部 "Wrong answer on test 5";

      看了一眼他人的AC代码,看到了 dp 数组,然后,想了好久好久的动态规划解法;

      wa 了改,改了 wa,终于,在下午临近吃饭的时候,AC了(大佬轻点虐)

      

      假设修改的区间为[ L,R ]

      那么,对于∀i∈[1,n], i = L or L < i < R or i = R;

      定义 dp[ i ][ j ],含义如下:

      j = 0 : i 作为修改区间的起始位置,从 i 开始向左能形成的最大区间和;

      j = 1 : i 作为修改区间的中间位置,从 i 开始向左能形成的最大区间和;

      j = 2 : i 作为修改区间的终点位置,i 可以形成的最大区间和;

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 using namespace std;
     5 #define INFll 0x3f3f3f3f3f3f3f3f
     6 #define ll long long
     7 #define mem(a,b) memset(a,b,sizeof(a))
     8 const int maxn=3e5+50;
     9 
    10 int n,x;
    11 ll a[maxn];
    12 /**
    13     在做*x的操作下
    14     dp[i][0]:i位置为修改区间的开始
    15     dp[i][1]:i位置为修改区间的中间部分
    16     dp[i][2]:i位置为修改区间的结尾
    17 */
    18 ll dp[maxn][3];
    19 /**
    20     在不做*x的操作下
    21     maxL[i]:以i开始的向左能形成的最大的区间和
    22     maxR[i]:以i开始的向右能形成的最大的区间和
    23 */
    24 ll maxL[maxn];
    25 ll maxR[maxn];
    26 
    27 ll Solve()
    28 {
    29     maxL[0]=-INFll;
    30     for(int i=1;i <= n;++i)
    31         maxL[i]=max(maxL[i-1]+a[i],a[i]);
    32     maxR[n+1]=-INFll;
    33     for(int i=n;i >= 1;--i)
    34         maxR[i]=max(maxR[i+1]+a[i],a[i]);
    35 
    36     dp[0][0]=dp[0][1]=0;
    37     for(int i=1;i <= n;++i)
    38     {
    39         dp[i][0]=x*a[i]+(maxL[i-1] > 0 ? maxL[i-1]:0);
    40         dp[i][1]=max(dp[i-1][0],dp[i-1][1])+x*a[i];
    41         dp[i][2]=max(dp[i][0],dp[i][1])+(maxR[i+1] > 0 ? maxR[i+1]:0);
    42     }
    43 
    44     ll ans=0;
    45     for(int i=1;i <= n;++i)
    46         ans=max(max(ans,maxL[i]),dp[i][2]);
    47 
    48     return ans;
    49 }
    50 int main()
    51 {
    52     while(~scanf("%d%d",&n,&x))
    53     {
    54         for(int i=1;i <= n;++i)
    55             scanf("%lld",a+i);
    56         printf("%I64d
    ",Solve());
    57     }
    58 }
    View Code

    巨巨代码(额外增加点我的注释)

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define mem(a,b) memset(a,b,sizeof(a))
     4 #define ll long long
     5 
     6 int n,x;
     7 ll a[300030];
     8 ll dp[300030][3];
     9 
    10 int main()
    11 {
    12     ll ans=0;
    13     cin>>n>>x;
    14     for(int i=1;i<=n;++i)
    15         cin>>a[i];
    16 
    17     mem(dp[0],0);
    18     /**
    19         dp[i][0]:[1,i]未使用*x所形成的最大区间和
    20         dp[i][1]:[L,i-1]使用*x,并且i也使用*x所形成的最大区间和
    21         dp[i][2]:[L,i-1]使用*x,但是i不使用*x所形成的最大区间和
    22     */
    23     for(int i=1;i<=n;++i)
    24     {
    25         dp[i][0]=a[i]+(dp[i-1][0] > 0 ? dp[i-1][0]:0);
    26         dp[i][1]=max(0LL,max(dp[i-1][0],dp[i-1][1]))+a[i]*x;
    27         dp[i][2]=max(0LL,max(dp[i-1][1],dp[i-1][2]))+a[i];
    28         for(int j=0;j<3;++j)//三者去最值
    29             ans=max(ans,dp[i][j]);
    30     }
    31     cout<<ans<<endl;
    32 
    33     return 0;
    34 }
    View Code
  • 相关阅读:
    Layui数据表格用法
    初识Vue
    使用NPOI导出Excel表
    使用NPOI将Excel表导入到数据库中
    新随笔
    AX2012/D365 SSRS报表开发
    AX2012自定义注释脚本开发
    D365做文件导入导出CSV
    Azure文件上传下载删除(D365可以直接用)
    关于D365/AX2012/C#中的那些json、对象、字符串类型间的转换
  • 原文地址:https://www.cnblogs.com/violet-acmer/p/10758836.html
Copyright © 2011-2022 走看看