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])\)即可。

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<algorithm>
  4. #include<cstring>
  5. #include<cmath>
  6. #include<queue>
  7. #include<map>
  8. #include<set>
  9. #define mk make_pair
  10. #define ll long long
  11. #define int long long
  12. using namespace std;
  13. inline int read()
  14. {
  15. int x=0,f=1;char ch=getchar();
  16. while (!isdigit(ch)) {if (ch=='-') f=-1;ch=getchar();}
  17. while (isdigit(ch)) {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
  18. return x*f;
  19. }
  20. const int maxn = 1e5+1e2;
  21. int n,m;
  22. int w[maxn],d[maxn];
  23. int f[maxn];
  24. int dis[maxn],val[maxn],sum[maxn];
  25. int sw[maxn];
  26. struct Point{
  27. int x,y,num;
  28. };
  29. Point q[maxn];
  30. int chacheng(Point x,Point y)
  31. {
  32. return x.x*y.y-x.y*y.x;
  33. }
  34. bool count(Point i,Point j,Point k)
  35. {
  36. Point x,y;
  37. x.x=k.x-i.x;
  38. x.y=k.y-i.y;
  39. y.x=k.x-j.x;
  40. y.y=k.y-j.y;
  41. if (chacheng(x,y)<=0) return true;
  42. return false;
  43. }
  44. int head=1,tail=0;
  45. void push(Point x)
  46. {
  47. while (tail>=head+1 && count(q[tail-1],q[tail],x)) tail--;
  48. q[++tail]=x;
  49. }
  50. void pop(int lim)
  51. {
  52. while(tail>=head+1 && q[head+1].y-q[head].y < lim * (q[head+1].x-q[head].x)) head++;
  53. }
  54. int g[maxn];
  55. signed main()
  56. {
  57. n=read();
  58. for (int i=1;i<=n;i++) w[i]=read(),d[i]=read(),dis[i]=d[i];
  59. for (int i=n-1;i>=1;i--) dis[i]+=dis[i+1];
  60. for (int i=1;i<=n;i++) sw[i]=sw[i-1]+w[i];
  61. for (int i=1;i<=n;i++) val[i]=w[i]*dis[i];
  62. for (int i=1;i<=n;i++) sum[i]=sum[i-1]+val[i];
  63. f[0]=sum[n];
  64. for (int i=1;i<=n;i++) f[i]=f[i-1]+sw[i-1]*d[i-1]-val[i];
  65. push((Point){0,f[0],0});
  66. for (int i=1;i<=n;i++)
  67. {
  68. pop((-1)*dis[i]);
  69. int now = q[head].num;
  70. g[i]=f[now]-(sw[i]-sw[now])*dis[i];
  71. push((Point){sw[i],f[i],i});
  72. }
  73. int now = q[head].num;
  74. int ans=1e18;
  75. ans=f[0];
  76. for (int i=1;i<=n;i++) ans=min(ans,g[i]);
  77. cout<<ans;
  78. return 0;
  79. }

洛谷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. docker搭建mysql集群

    目录 一.集群方案 二.安装PXC集群 三.Haproxy负载均衡 四.访问测试 五.节点宕机或重启 六.参考 一.集群方案 1.Replication 速度快,但仅能保证弱一致性,适用于保存价值不高 ...

  2. kubernetes部署一个应用程序

    文章原文 部署 nginx Deployment 如果你已经完成了Kubernetes的搭建,那我跟我一块来部署第一个应用程序吧.没有完成 Kubernetes 集群搭建的,请参考文档 使用 kube ...

  3. MongoDB索引的简单理解

    目录 MongoDB索引 1.语法准备 2.数据准备: 3.索引 3.1 唯一索引 3.2 单键索引 3.3 多键索引 3.4 复合索引 3.5 交叉索引 3.6 部分索引 3.7覆盖索引 3.8 全 ...

  4. jdbc核心技术-宋红康

    视频地址 JDBC核心技术 第1章:JDBC概述 1.1 数据的持久化 持久化(persistence):把数据保存到可掉电式存储设备中以供之后使用.大多数情况下,特别是企业级应用,数据持久化意味着将 ...

  5. 聊一聊开闭原则(OCP).

    目录 简述 最早提出(梅耶开闭原则) 重新定义(多态开闭原则) 深入探讨 OCP的两个特点 对外扩展开放(Open for extension) 对内修改关闭 抽象 关闭修改.对外扩展? 简述 在面向 ...

  6. 洛谷P1309——迷宫(傻瓜DFS)

    题目背景 迷宫 [问题描述] 给定一个N*M方格的迷宫,迷宫里有T处障碍,障碍处不可通过.给定起点坐标和 终点坐标,问: 每个方格最多经过1次,有多少种从起点坐标到终点坐标的方案.在迷宫 中移动有上下 ...

  7. Java基础系列(15)- 用户交互Scanner

    Scanner对象 之前我们学的基本语法中我们并没有实现程序和人的交互,但是Java给我们提供了这样一个工具类,我们可以获取用户的输入.java.util.Scanner是Java5的新特征.我们可以 ...

  8. Docker DevOps实战:GitLab+Jenkins(1)- GitLab容器搭建、使用SourceTree pull/push项目

    GitLab容器搭建 # 创建GitLab容器# --restart always #重启,容器自动重启# --privileged=true #容器内使用root权限 [root@localhost ...

  9. Leetcode 矩阵置零

    题目描述(中等难度) 给定一个 m x n 的矩阵,如果一个元素为 0 ,则将其所在行和列的所有元素都设为 0 .请使用 原地 算法. 进阶: 一个直观的解决方案是使用  O(mn) 的额外空间,但这 ...

  10. requests接口自动化-assert断言

    断言,自动判断接口返回的结果与预期结果是否一致 from common.get_mysql import * def test_assert(): a=0 b=1 # assert a,'断言失败打印 ...