力扣 每日一题 1326. 灌溉花园的最少水龙头数目难度:困难,rating: 1885(动态规划)
Posted nefu-ljw
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了力扣 每日一题 1326. 灌溉花园的最少水龙头数目难度:困难,rating: 1885(动态规划)相关的知识,希望对你有一定的参考价值。
题目链接
https://leetcode.cn/problems/minimum-number-of-taps-to-open-to-water-a-garden/
题目来源于:第172场周赛 Q4 rating: 1885
思路
得到所有区间,按左端点L、右端点R进行排序。然后遍历这些区间覆盖的每个点i,保证L<=i<=R,设dp[i]是覆盖[0,i]的线段最小个数,则有状态转移方程
d
p
[
i
]
=
m
i
n
(
d
p
[
i
]
,
d
p
[
L
]
+
1
)
dp[i]=min(dp[i],dp[L]+1)
dp[i]=min(dp[i],dp[L]+1)。
初始化dp=inf表示不可到达,遍历排序的区间保证 i 位置能从前一个 L 位置正确转移,如果发现dp[L]=inf则说明无法转移(接不上前面区间有断层)直接返回-1。
代码
class Solution
static const int N=10110,inf=0x3f3f3f3f;
int dp[N]; // 覆盖[0,i]的线段最小个数
vector<pair<int,int>> segments; // 线段
public:
int minTaps(int n, vector<int>& ranges)
for(int i=0;i<ranges.size();i++)
if(ranges[i]==0)continue; // 单个点无用
int x=max(0,i-ranges[i]);
int y=min(n,i+ranges[i]);
segments.push_back(make_pair(x,y));
sort(segments.begin(),segments.end());
memset(dp,inf,sizeof(dp));
dp[0]=0; // 注意初始化坐标0!
for(auto &[l,r]:segments) // 每次加一个区间进来
for(int i=l;i<=r;i++) // 遍历更新这个区间内的所有dp值
if(dp[l]==inf)
return -1;
dp[i]=min(dp[i],dp[l]+1);
return dp[n]==inf?-1:dp[n];
;
/*
7
[1,2,1,0,2,1,0,1]
ans: 3
*/
以上是关于力扣 每日一题 1326. 灌溉花园的最少水龙头数目难度:困难,rating: 1885(动态规划)的主要内容,如果未能解决你的问题,请参考以下文章
LeetCode 1326 灌溉花园的最少水龙头数目动态规划HERODING的LeetCode之路
数据结构与算法之深入解析“灌溉花园的最少水龙头数目”的求解思路与算法示例
《LeetCode之每日一题》:24. 制作 m 束花所需的最少天数