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. google搜索小技巧

    google搜索小技巧 一.总结 一句话总结:But most people may not be using Google search to its full potential.Want to ...

  2. MySQL utf8 和 utf8mb4 的区别

    utf-8 时变化长度的编码,储存一个code point 需要1~4个字节. 然而,mysql的utf8只存储最多3个字节per code point. 所以,utf8字符集不能存储所有的unico ...

  3. 掌握R语言中的apply函数族(转)

    转自:http://blog.fens.me/r-apply/ 前言 刚开始接触R语言时,会听到各种的R语言使用技巧,其中最重要的一条就是不要用循环,效率特别低,要用向量计算代替循环计算. 那么,这是 ...

  4. android-------- socket 实现客户端与服务器端通信

    前面介绍了Socket的简介和原理,今天简单的来实现一下客服端与服务器通信的功能 客服端 建立连接 try { socket = new Socket("192.168.1.100" ...

  5. 微信小程序选择图片,查看图片信息,浏览图片,图片上传

    依次点击链接请查看以下步骤 选择图片: https://mp.weixin.qq.com/debug/wxadoc/dev/api/media-picture.html#wxchooseimageob ...

  6. z-index注意事项

    1. z-index只对定位元素有效(如position:absolute!) 2. 被覆盖的元素将无法触发其鼠标相关事件.(个人经验,可能有例外.) 3. 无法通过z-index使父级覆盖子级,如果 ...

  7. Raspbian安装Opencv3

    如果旧版本使用apt-get安装 sudo apt-get remove libopencv sudo apt-get remove opencv 如果旧版本使用编译安装 sudo make unin ...

  8. 牛客练习赛41 B-666RPG

    题目链接:https://ac.nowcoder.com/acm/contest/373/B 题意:有n个回合,每个回合给1个数,每个回合你有两种选择 1.加上第i个数 2.将当前数乘-1 想知道有多 ...

  9. DVWA--XSS解题过程

    XSS概念:通常指黑客通过HTML注入纂改了网页,插入恶意脚本,从而在用户浏览网页时,控制用户浏览器的一种攻击. XSS有三种: 反射型xss:只是简单地把用户输入的数据反射给浏览器,简单来说,黑客往 ...

  10. Oracle 多表查询、查询运算符和集合运算

    一.多表查询 1.内连接 一般使用INNER JOIN关键字指定内连接,INNER可以省略,默认表示内连接.查询结果中只包含两表的公共字段值相等的行,列可以是两表中的任意列 2.外连接 包括左外连接. ...