题面

拆开式子我们发现切割顺序不影响答案,所以可以设计出一个$dp[i][j]$表示到$i$为止切了$j$刀的最大收益之类的,然后做个前缀和就可以转移了。

$dp[i][j]=min(dp[i][j],dp[k][j-1]+sum[k]*(sum[i]-sum[k]) )$

第一维显然还可以滚掉,这样就有了一个$O(n^2k)$的做法 因为跑不满如果再卡卡常大概可以得到50pts的好成绩

开始优化,假如现在在$i$而先不管切了几刀,有两个位置$j$和$k$满足$j<k$且$j$比$k$优,那么有

$dp[j]+sum[j]*(sum[i]-sum[j])<dp[k]+sum[k]*(sum[i]-sum[k])$

$dp[j]-sum[j]^2-(dp[k]-sum[k]^2)<(sum[k]-sum[j])*sum[i]$

$\frac{dp[j]-sum[j]^2-(dp[k]-sum[k]^2)}{(sum[k]-sum[j])}<sum[i]$

— —斜率优化,而sum[i]又是单增的,所以每次直接取队头就完事了

注意:因为是非负序列,可能会出现斜率不存在的情况,记得判掉

 #include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=,K=;
int n,k,f,b,p,tra[K][N],que[N];
long long sum[N],dp1[N],dp2[N];
double Slope(int a,int b)
{
if(sum[a]==sum[b]) return -1e9;
return 1.0*(sum[b]*sum[b]-dp1[b]-(sum[a]*sum[a]-dp1[a]))/(sum[b]-sum[a]);
}
int main()
{
scanf("%d%d",&n,&k);
for(int i=;i<=n;i++)
scanf("%lld",&sum[i]),sum[i]+=sum[i-];
for(int i=;i<=k;i++)
{
f=,b=-;
for(int j=;j<=n;j++)
{
while(f<b&&Slope(que[f],que[f+])<=sum[j]) f++;
p=que[f],dp2[j]=dp1[p]+(sum[j]-sum[p])*sum[p],tra[i][j]=p;
while(f<b&&Slope(que[b-],que[b])>=Slope(que[b],j)) b--;
que[++b]=j;
}
swap(dp1,dp2);
}
printf("%lld\n",dp1[n]),p=tra[k--][n];
while(p) printf("%d ",p),p=tra[k--][p];
return ;
}

解题:APIO 2014 序列分割的更多相关文章

  1. [APIO 2014] 序列分割

    [题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=3675 [算法] 首先 , 我们发现将一段序列切成若干段所获得的收益与顺序无关 于是我 ...

  2. 洛谷 P3648 [APIO2014]序列分割 解题报告

    P3648 [APIO2014]序列分割 题目描述 你正在玩一个关于长度为\(n\)的非负整数序列的游戏.这个游戏中你需要把序列分成\(k+1\)个非空的块.为了得到\(k+1\)块,你需要重复下面的 ...

  3. bzoj 3675: [Apio2014]序列分割

    Description 小H最近迷上了一个分隔序列的游戏.在这个游戏里,小H需要将一个长度为n的非负整数序列分割成k+1个非空的子序列.为了得到k+1个子序列,小H需要重复k次以下的步骤: 1.小H首 ...

  4. [Bzoj3675][Apio2014]序列分割(斜率优化)

    3675: [Apio2014]序列分割 Time Limit: 40 Sec  Memory Limit: 128 MBSubmit: 4021  Solved: 1569[Submit][Stat ...

  5. 【BZOJ-3675】序列分割 DP + 斜率优化

    3675: [Apio2014]序列分割 Time Limit: 40 Sec  Memory Limit: 128 MBSubmit: 1420  Solved: 583[Submit][Statu ...

  6. 【bzoj3675】 Apio2014—序列分割

    http://www.lydsy.com/JudgeOnline/problem.php?id=3675 (题目链接) 题意 给出一个包含n个非负整数的序列,要求将其分割成k+1个序列,每次分割可以获 ...

  7. bzoj 3675 [Apio2014]序列分割(斜率DP)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3675 [题意] 将n个数的序列分割k次,每次的利益为分割后两部分数值和的积,求最大利益 ...

  8. 【斜率DP】BZOJ 3675:[Apio2014]序列分割

    3675: [Apio2014]序列分割 Time Limit: 40 Sec  Memory Limit: 128 MBSubmit: 1066  Solved: 427[Submit][Statu ...

  9. 动态规划(斜率优化):BZOJ 3675 [Apio2014]序列分割

    Description 小H最近迷上了一个分割序列的游戏.在这个游戏里,小H需要将一个长度为N的非负整数序列分割成k+l个非空的子序列.为了得到k+l个子序列, 小H将重复进行七次以下的步骤: 1.小 ...

随机推荐

  1. docker 安装vim

    执行以下命令 apt-get update apt-get install vim

  2. ubuntu下Open vSwitch安装

    ubuntu下Open vSwitch安装 有关Open vSwitch的安装,网上有各种的教程资料,但一些已经过时,按照网上的教程,花费了大量时间,都没能安装成功.于是,通过查阅官方安装教程以及综合 ...

  3. The serializable class XXX does not declare a static final serialVersionUID field of type long的警告

    原文: http://blog.csdn.net/ultrakang/article/details/41820543

  4. maven学习资料(三)

    两个项目聚合到一个项目中: .

  5. [buaa-SE-2017]个人作业-Week2

    个人作业-Week2 一.代码复审Checklist 1.概要部分 1.1 代码能符合需求和规格说明么? 本次作业的需求可以分成基本的功能实现和大规模数据下程序的健壮性,以及少量的异常处理能力,也就是 ...

  6. Fast Packet Processing - A Survey

    笔记是边读边写的旁注,比较乱,没有整理就丢上来了. 可以说不仅要说fast packet process servey,也同时是一篇packet process的综述了.packet processi ...

  7. Java 线程结束 & 守护线程

    /* 停止线程: 1,stop方法. 2,run方法结束. 怎么控制线程的任务结束呢? 任务中都会有循环结构,只要控制住循环就可以结束任务. 控制循环通常就用定义标记来完成. 但是如果线程处于了冻结状 ...

  8. UIPickerView的使用

    简介:UIPickerView是一个选择器控件,它比UIDatePicker更加通用,它可以生成单列的选择器,也可生成多列的选择器,而且开发者完全可以自定义选择项的外观,因此用法非常灵活.UIPick ...

  9. windows下的C++ socket服务器(2)

    int main(int ac, char *av[]) { ); ) { exit(); } thread t; ) { int socket_fd = accept(tcp_socket, nul ...

  10. 讲讲Windows10(UWP)下的Binding

    前言 貌似最近来问我XAML这块的东西的人挺多的.有时候看他们写XAML这块觉着也挺吃力的,所谓基础不牢,地动山摇.XAML这块虽说和HTML一样属于标记语言,但是世界观相对更加庞大一点. 今天讲讲X ...