qwq

我感觉这都已经不算是斜率优化\(dp\)了,感觉更像是qwq一个\(下凸壳优化\)转移递推式子。

qwq

首先我们先定义几个数组

\(sw[i]\)表示\(w[i]\)的前缀和

\(val[i] = w[i]\times d[i]\)

\(sum[i]\)表示\(val[i]\)的前缀和。

\(dis[i]\)表示\(i\)到山脚下的距离

\(f[i]\)表示在\(i\)建第一个厂的最小代价。

一个比较容易发现的性质是,厂一定是建在老树的点上。

因为考虑我们在假设我们现在在一个非老树的点上,而左边的\(sw\)大于右边的\(sw\),那么我们现在向左边移动一定是更优秀的,右边大也是同理。

我们先考虑只建一个厂,也就是\(f[i]\)该如何求。

一个比较显然的递推$$f[i]=f[i-1]+sw[i-1]*d[i-1]-val[i]$$

表示在这个厂建的代价为在之前那个厂的代价+之前的树木从上个厂移动到这个厂的代价,减去这个厂下去的代价。

然后那我们应该怎么求\(g[i]\)呢,\(g[i]\)表示\(i\)之前有一个厂,且在\(i\)建第二个厂的最小代价。

\[g[i]=min(f[j]-(sw[i]-sw[j])*dis[i])
\]

这个式子表示在\(i\)这个地方建厂上,是在\(j\)的基础上,又把\(j到i\)的老树的路程进一步缩短了。

最后我们只需要输出\(min(g[i])\)即可。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<set>
#define mk make_pair
#define ll long long
#define int long long
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while (!isdigit(ch)) {if (ch=='-') f=-1;ch=getchar();}
while (isdigit(ch)) {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return x*f;
}
const int maxn = 1e5+1e2;
int n,m;
int w[maxn],d[maxn];
int f[maxn];
int dis[maxn],val[maxn],sum[maxn];
int sw[maxn];
struct Point{
int x,y,num;
};
Point q[maxn];
int chacheng(Point x,Point y)
{
return x.x*y.y-x.y*y.x;
}
bool count(Point i,Point j,Point k)
{
Point x,y;
x.x=k.x-i.x;
x.y=k.y-i.y;
y.x=k.x-j.x;
y.y=k.y-j.y;
if (chacheng(x,y)<=0) return true;
return false;
}
int head=1,tail=0;
void push(Point x)
{
while (tail>=head+1 && count(q[tail-1],q[tail],x)) tail--;
q[++tail]=x;
}
void pop(int lim)
{
while(tail>=head+1 && q[head+1].y-q[head].y < lim * (q[head+1].x-q[head].x)) head++;
}
int g[maxn];
signed main()
{
n=read();
for (int i=1;i<=n;i++) w[i]=read(),d[i]=read(),dis[i]=d[i];
for (int i=n-1;i>=1;i--) dis[i]+=dis[i+1];
for (int i=1;i<=n;i++) sw[i]=sw[i-1]+w[i];
for (int i=1;i<=n;i++) val[i]=w[i]*dis[i];
for (int i=1;i<=n;i++) sum[i]=sum[i-1]+val[i];
f[0]=sum[n];
for (int i=1;i<=n;i++) f[i]=f[i-1]+sw[i-1]*d[i-1]-val[i];
push((Point){0,f[0],0});
for (int i=1;i<=n;i++)
{
pop((-1)*dis[i]);
int now = q[head].num;
g[i]=f[now]-(sw[i]-sw[now])*dis[i];
push((Point){sw[i],f[i],i});
}
int now = q[head].num;
int ans=1e18;
ans=f[0];
for (int i=1;i<=n;i++) ans=min(ans,g[i]);
cout<<ans;
return 0;
}

洛谷4360[CEOI2004]锯木厂选址 (斜率优化+dp)的更多相关文章

  1. [CEOI2004]锯木厂选址 斜率优化DP

    斜率优化DP 先考虑朴素DP方程, f[i][k]代表第k个厂建在i棵树那里的最小代价,最后答案为f[n+1][3]; f[i][k]=min(f[j][k-1] + 把j+1~i的树都运到i的代价) ...

  2. 2018.08.28 洛谷P4360 [CEOI2004]锯木厂选址(斜率优化dp)

    传送门 一道斜率优化dp入门题. 是这样的没错... 我们用dis[i]表示i到第三个锯木厂的距离,sum[i]表示前i棵树的总重量,w[i]为第i棵树的重量,于是发现如果令第一个锯木厂地址为i,第二 ...

  3. 洛谷P4360 [CEOI2004]锯木厂选址(斜率优化)

    传送门 我可能根本就没有学过斜率优化…… 我们设$dis[i]$表示第$i$棵树到山脚的距离,$sum[i]$表示$w$的前缀和,$tot$表示所有树运到山脚所需要的花费,$dp[i]$表示将第二个锯 ...

  4. 洛谷P4360 [CEOI2004]锯木厂选址(dp 斜率优化)

    题意 题目链接 Sol 枚举第二个球放的位置,用前缀和推一波之后发现可以斜率优化 // luogu-judger-enable-o2 #include<bits/stdc++.h> #de ...

  5. P4360 [CEOI2004]锯木厂选址

    P4360 [CEOI2004]锯木厂选址 这™连dp都不是 \(f_i\)表示第二个锯木厂设在\(i\)的最小代价 枚举1号锯木厂 \(f_i=min_{0<=j<i}(\sum_{i= ...

  6. luoguP4360 [CEOI2004]锯木厂选址

    题目链接 luoguP4360 [CEOI2004]锯木厂选址 题解 dis:后缀和 sum:前缀和 补集转化,减去少走的,得到转移方程 dp[i] = min(tot - sumj * disj - ...

  7. 动态规划(斜率优化):[CEOI2004]锯木厂选址

    锯木场选址(CEOI2004) 从山顶上到山底下沿着一条直线种植了n棵老树.当地的政府决定把他们砍下来.为了不浪费任何一棵木材,树被砍倒后要运送到锯木厂. 木材只能按照一个方向运输:朝山下运.山脚下有 ...

  8. [BZOJ2684][CEOI2004]锯木厂选址

    BZOJ权限题! Description 从山顶上到山底下沿着一条直线种植了n棵老树.当地的政府决定把他们砍下来.为了不浪费任何一棵木材,树被砍倒后要运送到锯木厂. 木材只能按照一个方向运输:朝山下运 ...

  9. cogs 362. [CEOI2004]锯木厂选址

    ★★★   输入文件:two.in   输出文件:two.out   简单对比 时间限制:0.1 s   内存限制:32 MB 从山顶上到山底下沿着一条直线种植了n棵老树.当地的政府决定把他们砍下来. ...

随机推荐

  1. promise加载图片

    实现一个图片的加载:设置第一张图片加载1s之后加载第二张图片: <!DOCTYPE html> <html> <head> <meta charset=&qu ...

  2. 你知道 ES6~ES12等叫法是怎么来的吗?

    你知道 ES6~ES12等叫法是怎么来的吗? 前言 作为一名前端开发,学习 JavaScript 自是天经地义的事,但是,JavaScript 的发展历史是怎样的,恐怕有相当一部分人都不太了解. 我们 ...

  3. Spring Boot +Vue 项目实战笔记(二):前后端结合测试(登录页面开发)

    前言:关于开发环境 每位 Coder 都有自己偏好的开发工具,从大的方面划分主要有文本编辑器流和 IDE 流两种,我有一段时间也喜欢用编辑器(Sublime Text.Vim),但对我来说开发效率确实 ...

  4. CSS布局中最小高度的妙用

    CSS布局中最小高度的妙用 --最小高度可以设定一个BOX的最小高度,当其内容较少时时,也能保持BOX的高度为一定,超出就自动向下延伸最小高度可以设定一个BOX的最小高度,当其内容较少时时,也能保持B ...

  5. ---Docker学习随笔---基础管理部分---

    docker是什么?提供快速.高效.轻量的微服务平台 1. 背景介绍突破虚拟机对资源占用高.启动时间长.镜像存储大.集群规模小等限制,摆脱操作系统级的隔离级别,实现进程级管理.主要专用名词: chro ...

  6. Linux--MySQL 日志管理、备份与恢复

    MySQL 日志管理.备份与恢复一.MySQL 日志管理二.数据库备份的重要性与分类  1.数据备份的重要性  2.从物理与逻辑的角度,备份分为  3.从数据库的备份策略角度,备份可分为三.常见的备份 ...

  7. adb 常用命令大全(5)- 日志相关

    前言 Android 系统的日志分为两部分 底层的 Linux 内核日志输出到 /proc/kmsg Android 的日志输出到 /dev/log 语法格式 adb logcat [<opti ...

  8. 富文本编辑器-SpringBoot

    目录 简介 Editor.md 基础工程搭建 数据库设计 基础项目搭建 文章编辑整合(重点) 图片上传问题 表情包问题 文章展示 简介 项目地址:https://gitee.com/zwtgit/ri ...

  9. Mybatis-基本学习(上)

    目录 Mybatis mybatis开始 -----环境准备 一.简介 1.什么是MyBatis 2.持久化 3.持久层 4.为什么需要Mybatis? 二.第一个Mybatis程序 1.搭建环境 1 ...

  10. 在excel中,应用公式到多行

    当一个单元格中输入公式后, 选中单元格 然后将鼠标放到右下角的控制手柄处,当鼠标变成"黑十字"标志 双击鼠标左键 即可