最小平铺路径问题思路速览与代码详解(贪心算法)

一、问题描述

二、场景构建

包工头小刘要去铺路,工地给了一系列砖头,这些砖头长度不一,路是固定的,砖头肯定也能铺满,每块砖头能放的位置也是固定的,现在小刘要用最少的砖头铺完这一条路。

三、贪心策略选择

现在假设工地给的砖头已经按照砖头开始的地方从左到右(数轴数值从低到高),并且砖块长也从低到高排列了(即X中 l1 <= l2 <= ... <= ln,当 li = li+1 时,ui <= ui+1)

小刘决定使用这样的办法铺路:

每次选择的砖块,在保证能和前一块砖头相连接的情况下

优先选择能向前铺的路更多的砖头

四、代码及注释详解

此处给了一个样例为  X[7][2] = { {1,2},{1,6},{2,7},{4,8},{7,9},{8,10},{9,10}}

输出结果如下图所示:

分别打印最小平铺路径选择的砖块、最小平铺路径的长度

下面是代码及注释

#include <cstdlib>
#include <cstdio>
#include <iostream>

using namespace std;

// 贪心策略:
// 每次选择的砖块,在保证能和前一块砖块连接的基础上
// 尽量选择往前铺的路更多的

int Min_road(double X[][2], int size){
    int new_road = 0;                           // 最新的被选进最小平铺路径的砖块下标
    double cover_end = X[0][0];                 // 目前路径铺到哪里了(工程进度)
    int search = 0;                             // 找到第几块地砖了(目前遍历到的地砖下标)
    int count = 0;                              // 目前最小平铺路径中的地砖数量
    int X_length = size;
    

    // 遍历地砖,寻找最小平铺路径的地砖
    while(search < X_length){

        double blank_coverage = 0;              // 选择的地砖能再往前铺多少长度的路
        int bc_record = new_road;               // 选择的地砖的下标

        for(; search<X_length && X[search][0]<=cover_end; search++){    // 找的地砖开始不能和前一块脱节,就退出本次查找
            if(X[search][1]-X[new_road][1]>=blank_coverage){            // 如果当前地砖铺的路更多
                blank_coverage = X[search][1]-X[new_road][1];           // 记录这块地砖以及它铺的路的长度
                bc_record = search;
            }
        }

        new_road = bc_record;                   // 将地砖纳入最小平铺路径
        cover_end = X[new_road][1];             // 更新工程进度
        count++;                                // 更新砖块数量

        cout << "[" << X[new_road][0] << ", " << X[new_road][1] << "]  "; 

        if (X[new_road][1] == X[size-1][1])     // 路铺完了,立即结束工程
            break;
    }

    return count;
}

int main(){
    double X[7][2] = {
   
   {1,2},{1,6},{2,7},{4,8},{7,9},{8,10},{9,10}};
    int count = Min_road(X, 7);
    cout << '\n' << "长度为:" << count;
}

猜你喜欢

转载自blog.csdn.net/m0_56942491/article/details/124255485
今日推荐