斜率优化dp 笔记

任务安排1

有 N 个任务排成一个序列在一台机器上等待执行,它们的顺序不得改变。

机器会把这 N 个任务分成若干批,每一批包含连续的若干个任务。

从时刻 00 开始,任务被分批加工,执行第 i 个任务所需的时间是 Ti。

另外,在每批任务开始前,机器需要 S 的启动时间,故执行一批任务所需的时间是启动时间 S 加上每个任务所需时间之和。

一个任务执行后,将在机器中稍作等待,直至该批任务全部执行完毕。

也就是说,同一批任务将在同一时刻完成。

每个任务的费用是它的完成时刻乘以一个费用系数 Ci。

请为机器规划一个分组方案,使得总费用最小。

输入格式

第一行包含整数 N。

第二行包含整数 S。

接下来 N行每行有一对整数,分别为 Ti 和 Ci,表示第 i 个任务单独完成所需的时间 Ti 及其费用系数 Ci。

输出格式

输出一个整数,表示最小总费用。

数据范围

1≤N≤5000,
0≤S≤50,
1≤Ti,Ci≤100

输入样例:
5
1
1 3
3 2
4 3
2 3
1 4
输出样例:
153

 f[i]表示选好前i个任务的最小值

关键点在于把每次开始的S时间造成的全部后续影响加到当前这次的操作中,这样就不用考虑之前启动了几次机器了,取消了后效性

虽然过程中的f[1~n-1]的设计的值与状态设计不一定相同但f[n]一定是相同的 

#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define endl '\n'using namespace std;typedef pair<int, int> PII;
typedef long long ll;const int N = 5010;int n, S;
ll T[N], C[N], sum[N];
ll f[N];int main()
{IOScin >> n >> S;for(int i = 1; i <= n; i ++)cin >> T[i] >> C[i];for(int i = 1; i <= n; i ++){sum[i] = sum[i - 1] + C[i];T[i] += T[i - 1];}for(int i = 1; i <= n; i ++){f[i] = 2e18;for(int j = 1; j <= i; j ++)//[j, i]{//关键点在于把每次开始的S时间造成的全部后续影响加到当前这次的操作中//虽然过程中的f[1~n-1]的设计的值与状态设计不一定相同但f[n]一定是相同的 ll res = f[j - 1] + T[i] * (sum[i] - sum[j - 1]) + S * (sum[n] - sum[j - 1]);f[i] = min(f[i], res);}}cout << f[n];return 0;
}

任务安排2

有 N个任务排成一个序列在一台机器上等待执行,它们的顺序不得改变。

机器会把这 N 个任务分成若干批,每一批包含连续的若干个任务。

从时刻 0 开始,任务被分批加工,执行第 i 个任务所需的时间是 Ti。

另外,在每批任务开始前,机器需要 S 的启动时间,故执行一批任务所需的时间是启动时间 S 加上每个任务所需时间之和。

一个任务执行后,将在机器中稍作等待,直至该批任务全部执行完毕。

也就是说,同一批任务将在同一时刻完成。

每个任务的费用是它的完成时刻乘以一个费用系数 Ci。

请为机器规划一个分组方案,使得总费用最小。

输入格式

第一行包含整数 N。

第二行包含整数 S。

接下来 N 行每行有一对整数,分别为 Ti 和 Ci,表示第 i 个任务单独完成所需的时间 Ti 及其费用系数 Ci。

输出格式

输出一个整数,表示最小总费用。

数据范围

1≤N≤3×1e5,
1≤Ti,Ci≤512,
0≤S≤512

输入样例:
5
1
1 3
3 2
4 3
2 3
1 4
输出样例:
153

 除了数据范围其余和上一题一样

把j - 1看为 j可推出的公式:f[i]=f[j]+T[i]*(C[i]-C[j])+S*(C[n]-C[j])

可以发现当i固定时f[i]、C[i]、T[i]为定值,有两个未知量C[j]和f[j]

设f[j]为y,C[j]为x,整理一下式子

f[j]=(T[i] + S) * C[j] + f[i] - T[i]*C[i] - S*C[n]

约等于y = kx + b

可以发现截距b越小f[i]就越小,此时便来到了真正的斜率优化

找到下面最外围的凸包,找到第一个斜率大于k的那条边的左端点,此点就是在k斜率下到达y轴时最低的那个点(因为k>0° && k < 90°)

找这个凸包的办法:取出后两个点(x1,y1),(x2,y2)与当前点(x3,y3)比,如果第一个点和第二个点的斜率大于第一个点和第三个点的斜率就删掉最后一个点。循环往复。最后再加进这个点。

一般来说是用二分去找的

但这题还有点小性质,就是斜率k在不断变大,因此可以用类似双指针+单调队列的方式解决该问题(只是和单调队列很像)

任务安排3

有 N 个任务排成一个序列在一台机器上等待执行,它们的顺序不得改变。

机器会把这 N 个任务分成若干批,每一批包含连续的若干个任务。

从时刻 0 开始,任务被分批加工,执行第 i 个任务所需的时间是 Ti。

另外,在每批任务开始前,机器需要 S 的启动时间,故执行一批任务所需的时间是启动时间 S 加上每个任务所需时间之和。

一个任务执行后,将在机器中稍作等待,直至该批任务全部执行完毕。

也就是说,同一批任务将在同一时刻完成。

每个任务的费用是它的完成时刻乘以一个费用系数 Ci。

请为机器规划一个分组方案,使得总费用最小。

输入格式

第一行包含两个整数 N 和 S。

接下来 N 行每行有一对整数,分别为 Ti 和 Ci,表示第 i 个任务单独完成所需的时间 Ti 及其费用系数 Ci。

输出格式

输出一个整数,表示最小总费用。

数据范围

1≤N≤3×105,
0≤S,Ci≤512,
−512≤Ti≤512

输入样例:
5 1
1 3
3 2
4 3
2 3
1 4
输出样例:
153

这道题只能用二分了

过程会爆ll记得开int128

还有注意同一条线上的多个点只能存在最边缘的两个,中间的要全删掉

举个例子 

1、2两点都符合要求,但1更好,可能会错求成2

1、2两点都行,但要选1而不能选2

但我写的二分会找到最左边的点,所以不是这里的问题,思来想去与第二题还有一点不同,就是S和T下限从1变成了0,就会出现横坐标不变的情况,出现了斜率无限大的情况,所以出现了=的情况

类似的情况会出现,造成难以估量的bug,所以,凸包一定不要留线段中间的点!!!

#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define endl '\n'using namespace std;typedef pair<int, int> PII;
typedef long long ll;const int N = 300010;int n, S;
ll T[N], C[N];
ll f[N];
int q[N];int main()
{IOScin >> n >> S;for(int i = 1; i <= n; i ++)cin >> T[i] >> C[i];for(int i = 1; i <= n; i ++){C[i] += C[i - 1];T[i] += T[i - 1];}int hh = 0, tt = -1;q[++ tt] = 0;for(int i = 1; i <= n; i ++){int l = hh, r = tt;while(l < r){int mid = l + r >> 1;ll x1 = C[q[mid]], y1 = f[q[mid]];ll x2 = C[q[mid + 1]], y2 = f[q[mid + 1]];if(y2 - y1 >= (T[i] + S) * (x2 - x1))r = mid;else l = mid + 1;} int j = q[l];f[i] = f[j] + T[i] * (C[i] - C[j]) + S * (C[n] - C[j]);ll x3 = C[i], y3 = f[i];while(hh < tt){ll x1 = C[q[tt - 1]], y1 = f[q[tt - 1]];ll x2 = C[q[tt]], y2 = f[q[tt]];//注意一定是>= !!!!!!if((__int128)(y2 - y1) * (x3 - x1) >= (__int128)(y3 - y1) * (x2 - x1))tt --;else break;}q[++ tt] = i;}cout << f[n];return 0;
}

运输小猫

小 S 是农场主,他养了 M 只猫,雇了 P 位饲养员。

农场中有一条笔直的路,路边有 N 座山,从 1 到 N 编号。

第 i 座山与第 i−1 座山之间的距离为 Di。

饲养员都住在 1 号山。

有一天,猫出去玩。

第 i 只猫去 Hi 号山玩,玩到时刻 Ti 停止,然后在原地等饲养员来接。

饲养员们必须回收所有的猫。

每个饲养员沿着路从 1 号山走到 N 号山,把各座山上已经在等待的猫全部接走。

饲养员在路上行走需要时间,速度为 1 米/单位时间。

饲养员在每座山上接猫的时间可以忽略,可以携带的猫的数量为无穷大。

例如有两座相距为 1 的山,一只猫在 2 号山玩,玩到时刻 3 开始等待。

如果饲养员从 1 号山在时刻 2 或 3 出发,那么他可以接到猫,猫的等待时间为 0 或 1。

而如果他于时刻 1 出发,那么他将于时刻 2 经过 2 号山,不能接到当时仍在玩的猫。

你的任务是规划每个饲养员从 1 号山出发的时间,使得所有猫等待时间的总和尽量小。

饲养员出发的时间可以为负。

输入格式

第一行包含三个整数 N,M,P。

第二行包含 n−1 个整数,D2,D3,…,DN。

接下来 M 行,每行包含两个整数 Hi 和 Ti。

输出格式

输出一个整数,表示所有猫等待时间的总和的最小值。

数据范围

2≤N≤1e5,
1≤M≤1e5,
1≤P≤100,
1≤Di<1000,
1≤Hi≤N,
0≤Ti≤1e9

输入样例:
4 6 2
1 3 5
1 0
2 1
4 9
1 10
2 10
3 12
输出样例:
3

 

#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define endl '\n'using namespace std;typedef pair<int, int> PII;
typedef long long ll;const int N = 110, M = 100010;int n, m, p;
ll f[N][M];//前i个人,收回前j只猫
ll d[M], a[M];
int q[M];
ll sum[M];ll gety(int i, int k)
{return f[i - 1][k] + sum[k];
}int main()
{IOScin >> n >> m >> p;for(int i = 2; i <= n; i ++){cin >> d[i];d[i] += d[i - 1];}for(int i = 1; i <= m; i ++){int h, t;cin >> h >> t;a[i] = t - d[h];}sort(a + 1, a + 1 + m);for(int i = 1; i <= m; i ++)sum[i] = sum[i - 1] + a[i];memset(f, 0x3f, sizeof f);//排除i个人带回0只小猫的代价为0for(int i = 0; i <= p; i ++)f[i][0] = 0;//派出0个人只有可能带回0只小猫 即f[0][0] = 0;已被包含for(int i = 1; i <= p; i ++){int hh = 0, tt = -1;q[++ tt] = 0;for(int j = 1; j <= m; j ++){//先把斜率小于a[j]的去掉while(hh < tt && gety(i, q[hh + 1]) - gety(i, q[hh]) < a[j] * (q[hh + 1] - q[hh]))hh ++;int k = q[hh];f[i][j] = f[i - 1][k] - sum[j] + sum[k] + j * a[j] - k * a[j];ll x3 = j, y3 = gety(i, j);while(hh < tt){ll x1 = q[tt - 1], y1 = gety(i, q[tt - 1]);ll x2 = q[tt], y2 = gety(i, q[tt]);if((y2 - y1) * (x3 - x1) >= (y3 - y1) * (x2 - x1))tt --;else break;}q[++ tt] = j;}}cout << f[p][m];return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/779580.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

关于OLAP

OLAP和OLTP不同的是,表中单条记录本身并不是查询所关心的,比较典型的特点包括有聚合类算子、涉及多表Join,查询所用谓语/条件没有索引。由于这些操作都非常耗计算资源,而且数据仓库相比数据库在数据量上大很多,因此,OLAP类查询经常表现为cpu-bound而不是io-bound。 按照…

CSS使用JS变量

1. CSS变量 CSS 变量&#xff08;也称为自定义属性&#xff09;允许我们在 CSS 中定义可重复使用的值&#xff0c;并将其应用于不同的选择器。为了创建一个 CSS 变量&#xff0c;我们需要使用 -- 前缀&#xff0c;然后可以像常规属性一样使用它。 :root {--primary-color: bl…

HarmonyOS 应用开发之UIAbility组件启动模式

UIAbility的启动模式是指UIAbility实例在启动时的不同呈现状态。针对不同的业务场景&#xff0c;系统提供了三种启动模式&#xff1a; singleton&#xff08;单实例模式&#xff09;multiton&#xff08;多实例模式&#xff09;specified&#xff08;指定实例模式&#xff09;…

工厂能耗管控物联网解决方案

工厂能耗管控物联网解决方案 工厂能耗管控物联网解决方案是一种创新的、基于先进技术手段的能源管理系统&#xff0c;它深度融合了物联网&#xff08;IoT&#xff09;、云计算、大数据分析以及人工智能等前沿科技&#xff0c;以实现对工业生产过程中能源消耗的实时监测、精确计…

鸿蒙OS开发实战:【Socket小试MQTT连接】

本篇分享一下 HarmonyOS 中的Socket使用方法 将从2个方面实践&#xff1a; HarmonyOS 手机应用连接PC端 SocketServerHarmonyOS 手机应用连接MQTT 服务端 通过循序渐进的方式&#xff0c;全面了解实践HarmonyOS中的Socket用法 学习本章前先熟悉文档开发知识更新库gitee.com…

48 数列1

问题描述 : 思维的严密性是相当重要的&#xff0c;尤其是在程序设计中&#xff0c;一个小小的错误&#xff0c;就可能导致无法想象的后果。明明的爸爸是一名富有经验的程序设计专家&#xff0c;深知思维严密的重要性。于是在明明很小的时候&#xff0c;就通过游戏的方式训练明…

Python数据结构与算法学习指南

一、引言 在编程的世界里&#xff0c;数据结构与算法是构建高效、可靠程序的核心基石。Python&#xff0c;作为一种通用编程语言&#xff0c;不仅易于上手&#xff0c;而且提供了丰富的库和工具来支持各种数据结构和算法的实现。本文将指导你如何学习Python数据结构与算法&…

聊聊几个内存分析工具

本文结构&#xff1a; a、简介 b、简单示例 a、几个内存分析工具简介 Valgrind&#xff1a;这是一个功能强大的内存调试和性能分析工具&#xff0c;它可以检测出内存泄漏、非法内存访问等问题。对于C和C程序来说&#xff0c;Valgrind是一个非常有用的工具&#xff0c;它可以…

Pytorch入门实战 P4-猴痘图片,精确度提升

目录 一、前言&#xff1a; 二、前期准备&#xff1a; 1、设备查看 2、导入收集到的数据集 3、数据预处理 4、划分数据集&#xff08;8:2&#xff09; 5、加载数据集 三、搭建神经网络 四、训练模型 1、设置超参数 2、编写训练函数 3、编写测试函数 4、正式训练 …

[LeetCode][LCR 179]查找总价格为目标值的两个商品

题目 LCR 179. 查找总价格为目标值的两个商品 购物车内的商品价格按照升序记录于数组 price。请在购物车中找到两个商品的价格总和刚好是 target。若存在多种情况&#xff0c;返回任一结果即可。 示例 1&#xff1a; 输入&#xff1a;price [3, 9, 12, 15], target 18 输出&…

C语言例4-30:将一个正整数的各位数字逆序输出

算法分析&#xff1a; 提取某一个正整数的最末一位数字&#xff0c;采用取模10的余数获得&#xff0c;以此类推即可。 代码如下&#xff1a; //将一个正整数的各位数字逆序输出 #include<stdio.h> int main(void) {int i,r;printf("输入一个正整数&#xff1a; \…

代码随想录算法训练营第三十八天 | 509. 斐波那契数、70. 爬楼梯、746. 使用最小花费爬楼梯

代码随想录算法训练营第三十八天 | 509. 斐波那契数、70. 爬楼梯、746. 使用最小花费爬楼梯 509. 斐波那契数题目解法 70. 爬楼梯题目解法 746. 使用最小花费爬楼梯题目解法 感悟 509. 斐波那契数 题目 解法 使用动态规划 class Solution { public:int fib(int n) {if(n <…

如何准备科学海报

科学会议上的海报展示可以为早期职业研究人员提供宝贵的机会来练习他们的沟通技巧&#xff0c;获得有关他们研究的反馈&#xff0c;并扩大他们的网络。“通过与其他研究人员一对一地讨论我的工作&#xff0c;[我发现]我可以确定哪些工作做得好&#xff0c;哪些需要改进&#xf…

论文阅读,The Lattice Boltzmann Method: Principles and Practice(六)(1)

目录 一、流体模拟方法概述 二、传统的Navier-Stokes求解器 2.1 有限差分 2.2 有限体积法 2.3 有限元法 三、基于粒子的求解器 3.1 动力学理论 3.2 分子动力学 3.3 格子气体模型 3.4 耗散粒子动力学 3.5 多粒子碰撞动力学 3.6 直接模拟蒙特卡罗方法 3.7 平滑粒子流…

算法练习----力扣每日一题------1

原题链接&#xff1a; 2908. 元素和最小的山形三元组 I - 力扣&#xff08;LeetCode&#xff09; 题目解读&#xff1a; 给定一个整数数组nums&#xff0c;如果下标i,j,k满足 i<j<knums[i]<num[j]并且nums[k]<num[j] 则称为山型三元组&#xff0c;返回所有山型三…

0202矩阵的运算-矩阵及其运算-线性代数

文章目录 一、矩阵的加法二、数与矩阵相乘三、矩阵与矩阵相乘四、矩阵的转置五、方阵的行列式结语 一、矩阵的加法 定义2 设有两个 m n m\times n mn橘子 A ( a i j ) 和 B ( b i j ) A(a_{ij})和B(b_{ij}) A(aij​)和B(bij​),那么矩阵A与B的和记为AB,规定为 A B ( a 11…

SqlServer(4)经典总结大全-技巧总结-数据开发-基本函数-常识整理-经典面试题

六、技巧 1、11&#xff0c;12的使用&#xff0c;在SQL语句组合时用的较多 “where 11” 是表示选择全部 “where 12”全部不选&#xff0c; 如&#xff1a; if strWhere !‘’ begin set strSQL ‘select count(*) as Total from [’ tblName ] where ’ strWhere …

GEE22:基于目视解译的土地利用分类(随机森林监督分类)

采样点信息&#xff1a; 设置一下采样点参数&#xff1a; 代码&#xff1a; //设置研究区位置 var table ee.FeatureCollection("users/cduthes1991/boundry/China_province_2019"); var roi table.filter(ee.Filter.eq(provinces,beijing)); Map.centerObjec…

Golang基础-4

Go语言基础 介绍 基础 数组(array) 数组声明 元素访问与修改 数组遍历 关系运算 切片创建 多维数组 介绍 本文介绍Go语言中数组(array)操作(数组声明、元素访问与修改、数组遍历、关系运算、切片创建、多维数组)等相关知识。 基础 数组 数组是具有相同数据类型的…

函数重载和引用

目录 一&#xff1a;函数重载 1.1函数重载的概念 1.2为什么C支持函数重载&#xff0c;而C语言不支持呢&#xff1f; 1.2.1结论 1.2.2分析 二&#xff1a;引用 2.1引用概念 2.2引用特性 ​编辑 2.3常引用 2.4使用场景 一&#xff1a;函数重载 在自然语言中&#x…