力扣 每日一题 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)Java 求解灌溉花园的最少水龙头数目

《LeetCode之每日一题》:24. 制作 m 束花所需的最少天数

LeetCode每日一题(1482. 制作 m 束花所需的最少天数)

Educational Codeforces Round 37