Problem

给定一个长度为n的数字串,从中选取k个不重叠的子串(可以少选),将每个串求和si

求max|s1 - s2| + |s2 - s3| + ... + |sk - 1 - sk|(n <= 30000, k <= min(n, 200))

Solution

绝对值后的和,只和峰值和谷值的那些值有关(所以我们可以贪心峰值和谷值尽量多)

用f[i][j][k]表示前i个,分成j段,这个值在哪里(用k=0表示在谷值,k=1表示在谷值到峰值之间,k=2表示在峰值,k=3表示在峰值到谷值之间)

f[i][j][0] = max(f[i - 1][j][0], f[i - 1][j - 1][3]) - flag * x;

f[i][j][1] = max(f[i - 1][j][1], f[i][j][0]);

f[i][j][2] = max(f[i - 1][j][2], f[i - 1][j - 1][1]) + flag * x;

f[i][j][3] = max(f[i - 1][j][3], f[i][j][2]);

flag是什么呢?如果是第一个或者最后一个计算时只算一次,中间的都算两次

然后实际中,全部是峰值和谷值是不一定现实的,所以中间部分还要加上转移:

f[i][j][1] = max(f[i][j][1], f[i - 1][j - 1][1]);

f[i][j][3] = max(f[i][j][3], f[i - 1][j - 1][3]);

Notice

注意第一个或最后一个和其他地方是不一样的。

Code

#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define sqz main
#define ll long long
#define reg register int
#define rep(i, a, b) for (reg i = a; i <= b; i++)
#define per(i, a, b) for (reg i = a; i >= b; i--)
#define travel(i, u) for (reg i = head[u]; i; i = edge[i].next)
const int INF = 1e9, N = 30005, K = 205;
const double eps = 1e-6, phi = acos(-1.0);
ll mod(ll a, ll b) {if (a >= b || a < 0) a %= b; if (a < 0) a += b; return a;}
ll read(){ ll x = 0; int zf = 1; char ch; while (ch != '-' && (ch < '0' || ch > '9')) ch = getchar();
if (ch == '-') zf = -1, ch = getchar(); while (ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar(); return x * zf;}
void write(ll y) { if (y < 0) putchar('-'), y = -y; if (y > 9) write(y / 10); putchar(y % 10 + '0');}
int f[N][K][4];
int sqz()
{
int n = read(), k = read();
rep(i, 1, k)
rep(j, 0, 3) f[0][i][j] = -INF;
rep(i, 1, n)
{
int x = read();
rep(j, 1, k)
{
int flag = 2 - (j == 1 || j == k);
f[i][j][0] = max(f[i - 1][j][0], f[i - 1][j - 1][3]) - flag * x;
f[i][j][1] = max(f[i - 1][j][1], f[i][j][0]);
f[i][j][2] = max(f[i - 1][j][2], f[i - 1][j - 1][1]) + flag * x;
f[i][j][3] = max(f[i - 1][j][3], f[i][j][2]);
if (flag - 1)
{
f[i][j][1] = max(f[i][j][1], f[i - 1][j - 1][1]);
f[i][j][3] = max(f[i][j][3], f[i - 1][j - 1][3]);
}
}
}
printf("%d\n", max(f[n][k][1], f[n][k][3]));
}

[Codeforces513E2]Subarray Cuts的更多相关文章

  1. [CodeForces-513E2]Subarray Cuts

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

  2. Codeforces 513E2 Subarray Cuts dp (看题解)

    我们肯定要一大一小间隔开来所以 把式子拆出来就是类似这样的形式 s1 - 2 * s2 + 2 * s3 + ...... + sn 然后把状态开成四个, 分别表示在顶部, 在底部, 在顶部到底部的中 ...

  3. Rockethon 2015

    A Game题意:A,B各自拥有两堆石子,数目分别为n1, n2,每次至少取1个,最多分别取k1,k2个, A先取,最后谁会赢. 分析:显然每次取一个是最优的,n1 > n2时,先手赢. 代码: ...

  4. [LeetCode] Maximum Size Subarray Sum Equals k 最大子数组之和为k

    Given an array nums and a target value k, find the maximum length of a subarray that sums to k. If t ...

  5. [LeetCode] Minimum Size Subarray Sum 最短子数组之和

    Given an array of n positive integers and a positive integer s, find the minimal length of a subarra ...

  6. [LeetCode] Maximum Product Subarray 求最大子数组乘积

    Find the contiguous subarray within an array (containing at least one number) which has the largest ...

  7. [LeetCode] Maximum Subarray 最大子数组

    Find the contiguous subarray within an array (containing at least one number) which has the largest ...

  8. LeetCode 209 Minimum Size Subarray Sum

    Problem: Given an array of n positive integers and a positive integer s, find the minimal length of ...

  9. Leetcode Maximum Product Subarray

    Find the contiguous subarray within an array (containing at least one number) which has the largest ...

随机推荐

  1. python类中保存非绑定方法作为成员函数

    习惯了函数式,动不动传一个函数.但是直接把函数作为类方法保存,再调用时会报错. 举一个unittest时的例子 class MyTestCase(unittest.TestCase): @classm ...

  2. Dreamweaver 2

    1.CSS样式基本应用 1.1 概念 层叠样式表 <style type="text/css">body {background-color: #F00;} p{col ...

  3. Altium Designer PCB的时候 高亮显示引脚连线

    按住Ctrl ,左击连线,就可以高亮显示两个连接的引脚.

  4. 大数据 - spark-sql 常用命令

    --spark启动 spark-sql --退出 spark-sql> quit; --退出spark-sql or spark-sql> exit; 1.查看已有的database sh ...

  5. idataway_前端

    一半架构,一半标准.---纯属个人意见 ----------------------------------------- 基本的插件:(尽量使用iviews) 1.传输图片. 2.下拉框.日期控件. ...

  6. js时间戳如何转时间

    js时间戳如何转时间 一.总结 一句话总结:Date对象分别获取年now.getFullYear()月now.getMonth()+1日now.getDate()即可 Date对象分别获取年now.g ...

  7. C# 连接PDA扫码枪

    Symbol扫码枪开发文档 一.主要功能 实现symbol扫码枪和PC数据交互. 二.运行环境 SymbolMC32NO 三.开发工具与软件 开发环境:Win7 开发语言:C# 数据库:Sql Ser ...

  8. GrindEQ Math Utilities 2015破解版 图文安装和序列号补丁激活教程

    GrindEQ Math Utilities 2015破解版 图文安装和序列号补丁激活教程 https://www.sdbeta.com/mf/2018/1002/226048.html 软件下载: ...

  9. 解决无法安装Microsoft .Net Framework 3.5

    如果解决不了,试试我的方法吧,我也在网上找了好久,最终在本地解决了 所需工具:dism,和Net Framework 3.5,已经打包 链接:https://pan.baidu.com/s/1nKok ...

  10. CentOS7 安装Nginx 1.14:

      nginx-1.14.2.tar.gz:下载:wget http://nginx.org/download/nginx-1.14.2.tar.gz 安装nginx:   yum  install  ...