一、问题描述
二、场景构建
包工头小刘要去铺路,工地给了一系列砖头,这些砖头长度不一,路是固定的,砖头肯定也能铺满,每块砖头能放的位置也是固定的,现在小刘要用最少的砖头铺完这一条路。
三、贪心策略选择
现在假设工地给的砖头已经按照砖头开始的地方从左到右(数轴数值从低到高),并且砖块长也从低到高排列了(即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;
}