当前位置: 首页 > news >正文

线性预处理|dfs回溯

 

lc1921

按到达时间排序

class Solution {

public:

    int eliminateMaximum(vector<int>& dist, vector<int>& speed) 

    {

        int n = dist.size();

        vector<pair<int, int>> w;

        for (int i = 0; i < n; ++i) {

            w.push_back({dist[i], speed[i]});

        }

        sort(w.begin(), w.end(), [&](pair<int, int>& a, pair<int, int>& b) {

            // 到达时间

            return (a.first + a.second - 1) / a.second < (b.first + b.second - 1) / b.second;

        });

        int t = 0, ret = 0;

        for (int i = 0; i < n; ++i) {

            if (t < (w[i].first + w[i].second - 1) / w[i].second) {

                ret++;

                t++; 

            } else {

                break;

            }

        }

        return ret;

    }

};

 

lc08.02

回溯

带回溯的DFS

限定机器人仅向下/向右移动,标记已访问节点

if(a==m-1 && b==n-1)
        {
            found = true;
            return;

        }

 

并在路径无效时回溯

if(!found)  
            ret.pop_back();

 

寻找从网格左上角到右下角的可行路径(存在则返回路径,否则返回空数组)。

class Solution {
    int dx[2]={0,1};  
    int dy[2]={1,0};
    typedef pair<int,int> pii;
    int m,n;
    vector<vector<int>> ret,obstacleGrid;
    bool found = false;  // 标记是否找到路径

public:
    vector<vector<int>> pathWithObstacles(vector<vector<int>>& obstacleGrid) 
    {
        m=obstacleGrid.size();
        if(m==0) return {};
        n=obstacleGrid[0].size();
        this->obstacleGrid=obstacleGrid;
        if(obstacleGrid[0][0]==1)
            return {};
        ret.push_back({0,0});  // 先加入起点
        dfs(0,0);
        return found ? ret : vector<vector<int>>();
    }


    void dfs(int a,int b)
    {
        if(a==m-1 && b==n-1)
        {
            found = true;
            return;

        }


        for(int k=0;k<2;k++)  // 仅遍历向下、向右两种移动
        {
            int x=a+dx[k],y=b+dy[k];
            if(x>=0 && y>=0 && x<m && y<n && obstacleGrid[x][y]==0 && !found)
            {
                ret.push_back({x,y});
                obstacleGrid[x][y]=2;  // 标记为已访问
                dfs(x,y);


                if(!found)  // 若这条路径没找到,回溯(移除当前节点)
                    ret.pop_back();

            }
        }
    }
};

 

lc2100

预处理+线性校验

 

求解“适合抢劫银行的日子”:通过两个数组分别记录每个位置向左连续非递增、向右连续非递减的天数

 

最终筛选出两侧连续天数均不小于time的索引

 class Solution {
public:
    vector<int> goodDaysToRobBank(vector<int>& security, int time) {
        int n = security.size();
        vector<int> f1(n), f2(n);
        for(int i = 1, j = n-2; i < n; ++i, --j){
            if(security[i]<=security[i-1]) f1[i] = f1[i-1] + 1;
            if(security[j]<=security[j+1]) f2[j] = f2[j+1] + 1;
        }

        vector<int> ans;
        for(int i = time; i < n-time; ++i){
            if(f1[i] >= time && f2[i] >= time) ans.push_back(i);
        }
        return ans; 
    }
};

 

 

抽象

二维背包

 

lc474

三维dp

求解0-1二维背包问题的标准实现:在最多使用m个'0'和n个'1'的约束下,从字符串数组中选取最多字符串

 

三维dp表记录前i个字符串、j个'0'、k个'1'场景下的最大选串数

逐一生成字符串并决策选或不选以更新最优解

class Solution {
public:
    int findMaxForm(vector<string>& strs, int m, int n) 
    {
        int len=strs.size();
        vector<vector<vector<int>>> dp(len+1,vector<vector<int>>(m+1,vector<int>(n+1,0)));
        //0 个 元素 初始化为0

        for(int i=1;i<=len;i++)
        {
            for(int j=0;j<=m;j++)
            {
                for(int k=0;k<=n;k++)
                {
                    int a=0,b=0;
                    for(char& c:strs[i-1])
                    {
                        if(c=='0')
                            a++;
                        if(c=='1')
                            b++;
                    }

         //不选
                    dp[i][j][k]=dp[i-1][j][k];
                    if(j>=a && k>=b)
        //选
    dp[i][j][k]=max(dp[i][j][k],dp[i-1][j-a][k-b]+1);
                }
            }
        }
        return dp[len][m][n];
    }
};

 

二维背包_优化

 

在最多用 m 个“0”和 n 个“1”的限制下,从给定字符串数组中选最多的字符串(每个字符串含若干0和1)
 
核心:
 
1. 用 dp[j][k] 表示用 j 个0、k 个1能选到的最多字符串数;
2. 逐个遍历字符串,统计其含有的0和1数量;
3. 倒序更新 dp 表,判断是否能选当前字符串(不超0、1配额),选则更新最大数量

01背包_逆序

三维dp变二维时逆序遍历,是为了避免当前轮次刚更新的dp值被重复使用(即防止物品被多次选取) ,保证每个字符串仅被决策“选或不选”一次,符合0-1背包的核心规则。
 
- 逆序:先更新大j,再更新小j,保证用的是“上一轮未被当前字符串修改的旧值”,避免同一字符串被重复选。

- 正序:先更新小j,再更新大j,后续大j会用到当前轮已修改的新值,相当于同一字符串被多次选

class Solution {
public:
    int findMaxForm(vector<string>& strs, int m, int n) 
    {
        int len=strs.size();
        vector<vector<int>> dp(m+1,vector<int>(n+1,0));
        //0 个 元素 初始化为0

        for(int i=1;i<=len;i++)
        {
            for(int j=m;j>=0;j--)
            {
                for(int k=n;k>=0;k--)
                {
                    int a=0,b=0;
                //下标映射
                    for(char& c:strs[i-1])
                    {
                        if(c=='0')
                            a++;
                        if(c=='1')
                            b++;
                    }
            
                    if(j>=a && k>=b)    
    dp[j][k]=max(dp[j][k],dp[j-a][k-b]+1);
                }
            }
        }
        return dp[m][n];
    }
};

 

lc879

class Solution {
        typedef long long ll;
public:
    int profitableSchemes(int n, int m, vector<int>& group, vector<int>& profit) 
    {
        int w=group.size();
        vector<vector<ll>> dp(n+1,vector<ll>(m+1));
        //针对 dp[0][j][0]=1 //没工作 有人 没利润
        for(int j=0;j<=n;j++)
            dp[j][0]=1;
        for(int i=1;i<=w;i++)
        {
            //xia biao
            for(int j=n;j>=group[i-1];j--)
            {
                for(int k=m;k>=0;k--)
                {
                    dp[j][k]+=dp[j-group[i-1]][max(0,k-profit[i-1])];
                    dp[j][k]%=(ll)(1e9+7);
                }
            }
        }
        return dp[n][m]; 
    }
};

 

http://www.dtcms.com/a/598729.html

相关文章:

  • VGG改进(15):Sparse Attention在VGG16中的设计与实现
  • 常州外贸网站制作弄一个电影网站怎么做
  • 网站信息评估抽查电子商务网站建设技术解决方案
  • 沈阳开发网站公司做销售的去哪个网站应聘
  • 树莓派5+Ubuntu24.04 LTS CH348 / CH9344 驱动安装 保姆级教程
  • 网站的功能和作用是什么上海方正大厦网站建设
  • Unity:lua热更新(二)——Lua语法(续)
  • 设计门户网站wordpress怎么装模板
  • Blender科幻机甲娘莉莉魅魔人物角色3D模型带骨骼动作绑定带贴图
  • 网站源码下载工具民间it网站建设
  • 松江工业区网站建设钱追得回吗
  • 数据库之增删改查
  • C# 生成指定位数的编号
  • 房地产网站建设哪家有效果网站开发工作分解结构
  • SAP FICO资产主数据查询接口
  • 婚恋网站开发做指甲的网站
  • 【IEEE出版、往届均检索】第三届智慧城市与信息系统国际学术会议 (ICSCIS 2026)
  • 国外免费wordpress温州谷歌优化公司
  • 开封网站建设公司排名建网站郑州
  • 成都建设银行网站flash 做网站教程
  • 企业网站 报价二级域名分发站免费
  • Android 开发 - Android JNI 开发关键要点
  • 延时芯片EH3B05上电延时3秒开关机芯片方案超低功耗
  • 神经 网络
  • 淮安企业网站制作网站重新备案 需要关闭网站么
  • elementor做视频网站网页设计基础教程
  • 编程语言排行 | 探讨当前热门编程语言的应用与发展趋势
  • 访问同一网站多次做家政有专门的网站吗
  • 石家庄网站建设外包公司百度推广后台登陆入口
  • 做网站设计制作的公司网站建设与管理 ppt