递归:求所需的快递员最少位数
题目简介
- 描述:有一快递配送线路arr[], arr[i]=0时表示无需配送,arr[i]=1时表示需要配送。
- 条件:每个快递员只能配送连续的三个点,即arr[i-1],arr[i],arr[i+1]
- 输出:输入arr[],输出最少需要快递员的数量
解答
#include <iostream>
#include "vector"
using namespace std;
class Solution {
public:
int Postman(const vector<int> &arr)
{
vector<int> myVec = arr;
int iCount = 0;
if (arr.size() < 1 || arr.size() > 100000) {
return 0;
}
if (arr.size() <= 3) {
for (int i = 0; i < arr.size(); i++) {
if (arr[i] == 1) {
iCount = 1;
}
}
return iCount;
}
if (arr[0] == 0) {
myVec.erase(myVec.begin());
} else {
bool bResult = arr[0] == 0 && arr[1] == 0 && arr[2] == 0;
myVec.erase(myVec.begin(), myVec.begin() + 3);
iCount++;
}
return iCount += Postman(myVec);
}
};
int main()
{
Solution *so = new Solution();
cout << so->Postman(vector<int> { 0, 0, 1, 0, 0, 1 }) << endl; // 2
cout << so->Postman(vector<int> { 1, 0, 1 }) << endl; // 1
cout << so->Postman(vector<int> { 1, 0, 1, 0, 1, 0, 1 }) << endl; // 2
cout << so->Postman(vector<int> { 1, 1, 1, 1 }) << endl; // 2
cout << so->Postman(vector<int> { 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0 }) << endl; // 3
cout << so->Postman(vector<int> { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }) << endl; // 4
cout << so->Postman(vector<int> { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }) << endl; // 4
cout << so->Postman(vector<int> { 1, 1, 1, 1, 1, 1, 1, 1, 1 }) << endl; // 3
cout << so->Postman(vector<int> { 0, 0, 0, 0, 1, 1, 1, 0 }) << endl; // 1
free(so);
return 0;
}
分析
-
教训:当时公司考试时为了图方便和赶时间,直接以三个一组用for循环去处理,但是处理到最后总有用例通不过。原因就是对0的处理出现的问题,导致最终不是最少解。当时其实已经发现了问题,但是依然头铁强行for去处理,导致问题变得极其复杂。后来转念一想,寥寥数行递归可以很好的解决该问题。
-
解析:当前arr首位非0时,可以肯定,已当前首位和其后续2位,都是必然需要安排一位快递员的。当遇到0时,应当考虑该快递员能否再往前一个快递点,已保障出现不必要的结果。然后截取子数组,递归处理

浙公网安备 33010602011771号