#C. gsy 的浇水计划(线段树+dp)

news/2024/10/11 16:45:29/

题目


思路

考的知识点是线段树+dp

我们可以按照dp 4步法来一步步推导、

1.dp定义

dp[i]代表[1,i]区间被给出线段覆盖最小花费

2.状态转移方程

根据dp定义可得当枚举到第x条线,区间为[Lx,Rx],花费为Vx

dp[Rx]=min(dp[i](i = (Lx - 1) ~ Rx))+Vx

因为当想要覆盖[1,Rx]的区间就必须在覆盖[1,Lx - 1]/[1,Lx]……/[1,Rx]的基础上再加上第x条线段

覆盖[1,Lx - 1]/[1,Lx]……/[1,Rx]最小花费就是(dp[i](i = (Lx - 1) ~ Rx),再加上第x条线段的花费是Vx

画个图来理解:

这个时候会有个问题:在这里我们要求min(dp[i](i = (Lx - 1) ~ Rx),可是如果暴力枚举找min的话时间复杂度O(n*m)会超时,那该怎么办呢?我们可以用线段树(详见详解线段树)来实现查找区间最小值单点更新(dp在变)的效果。

3.初始化

一个是dp一开始要是无穷大,一个是minv(线段树的那个)也要初始化为无穷大,另外储存线段的数组也要以r从大到小排序(这样才能保证后续枚举线段时dp[i](i = (Lx - 1) ~ Rx是最优的)

4.遍历顺序

显然就是以下标顺序枚举所有线段。


代码

#include <bits/stdc++.h>
#define int long long
#define maxn 300000
using namespace std;
int n,m,dp[5000000],minv[5000000];
struct shui
{int l,r,v;
} a[5000000];
bool cmp(shui x,shui y)
{return x.r < y.r;
}
int find(int id,int l,int r,int x,int y)//查找[x,y]区间内的最小值
{if(x <= l && r <= y) return minv[id];int mid = (l + r) / 2,ans = INT_MAX;if(x <= mid) ans = min(ans,find(id * 2,l,mid,x,y));if(y > mid) ans = min(ans,find(id * 2 + 1,mid + 1,r,x,y));return ans;
}
void gexi(int id,int l,int r,int x,int v)//将编号为x的节点的值更改为v
{if(l == r){minv[id] = v;return ;}int mid = (l + r) / 2;if(x <= mid) gexi(id * 2,l,mid,x,v);else gexi(id * 2 + 1,mid + 1,r,x,v);minv[id] = min(minv[id * 2],minv[id * 2 + 1]);
}
signed main()
{scanf("%lld%lld",&n,&m);for(int i = 1; i <= n; i++) scanf("%lld%lld%lld",&a[i].l,&a[i].r,&a[i].v);memset(dp,0x3f,sizeof(dp));memset(minv,0x3f,sizeof(minv));//minv对应的是dpsort(a + 1,a + 1 + n,cmp);for(int i = 1; i <= n; i++){if(a[i].l == 1){if(dp[a[i].r] > a[i].v){dp[a[i].r] = a[i].v;gexi(1,1,maxn,a[i].r,a[i].v);}}else{int t = find(1,1,maxn,a[i].l - 1,a[i].r);if(dp[a[i].r] > (t + a[i].v)){dp[a[i].r] = t + a[i].v;gexi(1,1,maxn,a[i].r,dp[a[i].r]);}}}printf("%lld",dp[m]);return 0;
}

http://www.ppmy.cn/news/22645.html

相关文章

一文带你熟悉内核调试工具 --Ftrace

&#x1f446;&#x1f440;前言Ftrace是一个内部跟踪程序&#xff0c;旨在帮助软件开发人员和系统的设计者去发现内核内部发生了什么。它可以用于调试或分析延迟和发生在用户空间之外的性能问题。ftrace通常被认为是函数跟踪程序&#xff0c;但它实际上是由几个不同的跟踪实用…

SpringBoot第三讲

三、SpringBootMybatisPlusVue增删改查 3.1 查询 后台查询代码&#xff1a; RestController RequestMapping("/t-user") public class TUserController { ​Resourceprivate ITUserService itUserService; ​/*** 查询所有的数据*/GetMappingpublic Result getAll…

一文弄懂Docker基本使用

文章目录初识Docker什么是Docker应用部署的环境问题Docker解决依赖兼容问题Docker解决操作系统环境差异小结Docker和虚拟机的区别Docker架构镜像和容器DockerHubDocker架构小结安装DockerDocker的基本操作镜像操作镜像名称镜像命令案例-拉取、查看镜像案例-保存、导入镜像容器操…

【每日一题Day108】LC1798你能构造出连续值的最大数目 | 贪心

你能构造出连续值的最大数目【LC1798】 You are given an integer array coins of length n which represents the n coins that you own. The value of the ith coin is coins[i]. You can make some value x if you can choose some of your n coins such that their values …

testbench常用语句

与可综合Verilog代码所不同的是&#xff0c;testbench Verilog是在计算机主机上的仿真器中执行的。testbench Verilog的许多构造与C语言相似&#xff0c;我们可在代码中包括复杂的语言结构和顺序语句的算法。 1 always块和initial块 Verilog有两种进程语句&#xff1a;always…

Python爬虫教你爬取视频信息

大家好&#xff0c;我是拉斯&#xff0c;今天分享一个爬取某音视频的一个小案例&#xff0c;大家一起学习 目录前言基本环境配置爬取目标视频获取视频链接1.查看网页源代码2.抓包工具捕捉下载视频(以mp4格式进行保存)获取其他信息并打印(作者名&#xff0c;作品名&#xff0c;…

Go异步任务解决方案 Asynq

今天为大家介绍一个Go处理异步任务的解决方案&#xff1a;Asynq&#xff0c;是一个 Go 库&#xff0c;用于排队任务并与 worker 异步处理它们。它由Redis提供支持&#xff0c;旨在实现可扩展且易于上手。 一、概述 Asynq 是一个 Go 库&#xff0c;用于对任务进行排队并与工作人…

软件测试-python-UnitTest-笔记

UnitTestunittest是Python单元测试框架&#xff0c;类似于JUnit框架。unittest中有4个重要的概念&#xff1a;test fixture, test case, test suite, test runnerTestcase&#xff1a;一个TestCase的实例就是一个测试用例。什么是测试用例呢&#xff1f;就是一个完整的测试流程…