(nice!!!)LeetCode 2742. 给墙壁刷油漆(数组、动态规划dp || 记忆化搜索dfs)

2742. 给墙壁刷油漆

在这里插入图片描述
在这里插入图片描述

思路:方法一,记忆化搜索dfs。对于每一堵墙,都有两种状态,选和不选。
最后选择结果一定满足:所选墙的时间之和>=免费墙的个数。
在这个条件下,尽可能减少开销。细节看注释,时间复杂度0(n^2)

class Solution {
public:
    int inf=5e8+10;//用于不满足条件时:即所选墙的时间之和<免费墙的个数
    int v[550][1100];//存储遍历过的状态,第一维是墙的下标,第二维是:所选墙的时间之和“减去”免费墙的个数,这里1100,是因为它两之差中间可能存在负数,但是最大也不超过550
    int dfs(int u,int res,vector<int>& cost, vector<int>& time){
    	//当res>u时,也就是剩下的都可以通过免费来实现
        if(res>u) return 0;
        //遍历完了,还是没有达到res>u的要求,返回不可能
        if(u==-1) return inf;
        //查看是否经历过这个状态,+550的原因就是因为res会存在负数
        if(v[u][res+550]!=-1) return v[u][res+550];
        //然后就是比较选与不选的最优值。
        return v[u][res+550]=min(dfs(u-1,res+time[u],cost,time)+cost[u],dfs(u-1,res-1,cost,time));
    }
    int paintWalls(vector<int>& cost, vector<int>& time) {
    	//先把状态都初始化为没有到达过
        memset(v,-1,sizeof v);
        //参数:墙的下标、所选墙的时间之和“减去”免费墙的个数、cost、time
        return dfs(cost.size()-1,0,cost,time);
    }
};

思路:方法二,动态规划dp。最后选择结果一定满足:
1、所选墙的时间之和>=免费墙的个数。
2、所选墙的个数+免费墙的个数=n
结合以上两个条件可以推出:所选墙的(时间+1)>=n,即:所有付费墙Time+付费墙的个数>=n。
可以理解为0-1背包问题,即在n个墙里面,选出的m个墙,这m个墙的时间time之和,再加上m要>=n,同时支持最小。细节看注释,时间复杂度0(n^2)

class Solution {
public:
    int paintWalls(vector<int>& cost, vector<int>& time) {
        int n=cost.size();
        //初始化状态
        vector<int> dp(n+1,500000010);
        dp[0]=0;
        // 0-1背包问题
        for(int i=0;i<cost.size();i++){
            for(int j=n;j>0;j--){
                dp[j]=min(dp[j],dp[max(0,j-(time[i]+1))]+cost[i]);
            }
        }
        return dp[n];
    }
};
  • 12
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值