• [CodeForces-513E2]Subarray Cuts


    题目大意:
      给你一个数列,从中选出k个互不重叠的非空子串,定义s[i]为第i个子串的和,求|s[1]-s[2]|+|s[2]-s[3]|+...+|s[k-1]-s[k]|的最大值。

    思路:
      考虑将绝对值去掉,对于连续一段和单调的子串,结果只与其中峰值和谷值有关,中间的数会直接消掉。
      我们用f[i][j][0..3]表示在第i个数时总共选了j和子串时的状态。
      其中第三维为0时,表示当前子串为谷值。
      第三维为2时,表示当前子串为峰值。
      第三维为1时,表示当前子串在谷值到峰值之间。
      第三维为3时,表示当前子串在峰值到谷值之间。
      也不需要前缀和,因为你按每一个数DP,答案可以直接加上去。
      注意考虑边界情况,当j=1或k的时候只用加/减一次,当j!=1或k的时候,这个子串同时会时前、后两段的峰/谷值,要加/减两次。

     1 #include<cstdio>
     2 #include<cctype>
     3 #include<algorithm>
     4 inline int getint() {
     5     register char ch;
     6     register bool neg=false;
     7     while(!isdigit(ch=getchar())) if(ch=='-') neg=true;
     8     register int x=ch^'0';
     9     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
    10     return neg?-x:x; 
    11 }
    12 const int _inf=-0x40000000;
    13 const int N=30001,K=201;
    14 int a[N];
    15 int f[N][K][4];
    16 int main() {
    17     int n=getint(),k=getint();
    18     for(register int i=1;i<=n;i++) {
    19         a[i]=getint();
    20     }
    21     for(register int j=1;j<=k;j++) {
    22         for(register int k=0;k<=3;k++) {
    23             f[0][j][k]=_inf;
    24         }
    25     }
    26     for(register int i=1;i<=n;i++) {
    27         for(register int j=1;j<=k;j++) {
    28             const int s=a[i]*((j!=1&&j!=k)?2:1);
    29             f[i][j][0]=std::max(f[i-1][j][0],f[i-1][j-1][3])-s;//谷值 
    30             f[i][j][1]=std::max(f[i-1][j][1],f[i][j][0]);//谷值-峰值 
    31             f[i][j][2]=std::max(f[i-1][j][2],f[i-1][j-1][1])+s;//峰值 
    32             f[i][j][3]=std::max(f[i-1][j][3],f[i][j][2]);//峰值-谷值 
    33             if(j!=1&&j!=k) {//上一段也在峰值和谷值之间 
    34                 f[i][j][1]=std::max(f[i][j][1],f[i-1][j-1][1]);
    35                 f[i][j][3]=std::max(f[i][j][3],f[i-1][j-1][3]);
    36             }
    37         }
    38     }
    39     printf("%d
    ",std::max(f[n][k][1],f[n][k][3]));
    40     return 0;
    41 }
  • 相关阅读:
    java.lang.ExceptionInInitializerError异常分析
    项目中碰到的ExceptionInInitializerError异常
    获取全局上下文(getApplicationContext)_创建Shared Preference工具类_实现自动登录
    IntelliJ Idea 常用快捷键列表
    Qt 创建圆角、无边框、有阴影、可拖动的窗口 good
    去掉 Windows 中控件的虚线框(当当 element == QStyle::PE_FrameFocusRect 时,直接返回,不绘制虚线框)
    Qt 显示 GIF
    C++ 查看预处理后的源文件(查看真实代码)
    数据库访问工具 DBUtl(公孙二狗)
    Tornado
  • 原文地址:https://www.cnblogs.com/skylee03/p/7649069.html
Copyright © 2020-2023  润新知