过桥问题,有几辆车顺序通过一个单向小桥

过桥问题(bridge)
问题描述:
现在有n辆车要按顺序通过一个单向的小桥,由于小桥太窄,不能有两辆车
并排通过,所以在桥上不能超车。另外,由于小桥建造的时间已经很久,所以只
能承受有限的重量,记为Load(吨),即任意时刻在桥上行驶的车辆的总重量不
能超过Load(吨)。因此,车辆在过桥的时候必须有管理员控制,将这N辆车按
初始的顺序分组,每次让一个组过桥,并且只有在一个组中的所有的车辆全部过

有原题,不过代码是C的,下面我改出C++的代码了。
原题连接:

【DTOJ Begin】1019. 过桥(bridge)_n辆车正在一条宽度只能容纳一辆车的隧道里疾速行进着,当速度快的车辆i追上速度慢_o_Invincible_o的博客-CSDN博客 目录题目描述输入格式输出格式样例SolutionAC Code题目描述现有N辆车要按顺序通过一个单向的小桥,由于小桥太窄,不能有两辆车并排通过。另外,由于小桥建造的时间已经很久,只能承受有限的重量,记为Max(吨)。管理员将N辆车按初始的顺序分组,每次让一个组过桥,并且只有在一个组的车辆全部过桥后,下一组车辆才能上桥。每辆车的重量和最大速度是已知的,而每组车的过桥时间由该组中速度最慢的那辆车决定。请你帮管理员编一个程序,将这N辆车分组,使得全部车辆通过小桥的时间最短。输入格式第一行有3个数字,分别为_n辆车正在一条宽度只能容纳一辆车的隧道里疾速行进着,当速度快的车辆i追上速度慢 https://blog.csdn.net/o_Invincible_o/article/details/123977730

改成C++代码:

#include <iostream>
#include <iomanip>
#include <algorithm>
using namespace std;

const int N = 1005;

int m, n;
int s[N];
double g[N][N], f[N], l, v;

int main()
{
    cin >> m >> l >> n;
    for (register int i = 1; i <= n; i++)
    {
        cin >> s[i] >> g[i][i];
        s[i] += s[i - 1]; g[i][i] = (l / g[i][i]) * 60;
    }
    for (register int i = 1; i <= n; i++)
    {
        for (register int j = i + 1; j <= n; j++)
            g[i][j] = max(g[i][j - 1], g[j][j]);
    }
    for (register int i = 1; i <= n; i++)
    {
        f[i] = 1e9; //double不要用memset
        for (register int j = 1; j <= i; j++)
            if (s[i] - s[j - 1] <= m) f[i] = min(f[i], f[j - 1] + g[j][i]);
    }
    cout << fixed << setprecision(1) << f[n] << endl; //setprecision(1) 保留1位小数
    
    return 0;
}


题目不完整吧,题目的输入、输出是怎样的。

【以下回答由 GPT 生成】

解决方案

这是一个经典的过桥问题,可以使用递归的方式来解决。具体的步骤如下:

  1. 首先,我们需要定义一个函数 crossBridge,该函数的输入参数包括车辆数组、当前乘坐桥上的车辆数组、当前过桥的车辆数量、当前过桥的总重量以及最大承载重量。函数的返回值是一个整数,表示当前过桥的最小时间。

  2. crossBridge 函数中,我们首先判断是否已经过完了所有车辆。如果是,则返回0,表示已经过完了所有车辆并且不需要额外的等待时间。

  3. 如果还有车辆待过桥,我们需要分别尝试将下一辆车加入到桥上并计算相应的时间。

  4. 假设当前过桥的车辆数量为 count,总重量为 weight。我们从车辆数组中选出下一辆车,加入到桥上。然后,我们需要判断这辆车是否能够通过桥口,并且桥上的车辆总重量不超过最大承载重量。如果满足条件,我们可以将这辆车加入到桥上,更新 count 和 weight。

  5. 接下来,我们需要递归地调用 crossBridge 函数来计算继续过桥的最小时间。在计算完下一辆车后,我们需要将桥上的车辆数量和总重量恢复到之前的值,以便于计算其他方案。

  6. 最后,我们选择其中最小的时间作为结果返回。

下面是用 C++ 实现的代码:

#include <iostream>
#include <vector>

using namespace std;

int crossBridge(vector<int>& cars, vector<int>& bridge, int count, int weight, int load) {
    // 如果已经过完了所有车辆,返回0
    if (count == cars.size()) {
        return 0;
    }

    int minTime = INT_MAX;

    // 尝试将下一辆车加入桥上并计算相应时间
    for (int i = 0; i < cars.size(); i++) {
        if (bridge.empty() || weight + cars[i] <= load) {
            bridge.push_back(cars[i]);
            int nextTime = crossBridge(cars, bridge, count + 1, weight + cars[i], load);
            minTime = min(minTime, bridge[i] + nextTime);
            bridge.pop_back();
        }
    }

    return minTime;
}

int main() {
    int n;
    vector<int> cars;

    cout << "请输入车辆数量: ";
    cin >> n;

    cout << "请输入每辆车的重量: ";
    for (int i = 0; i < n; i++) {
        int weight;
        cin >> weight;
        cars.push_back(weight);
    }

    int load;
    cout << "请输入桥的最大承载重量: ";
    cin >> load;

    vector<int> bridge;
    int count = 0;
    int weight = 0;
    int minTime = crossBridge(cars, bridge, count, weight, load);

    cout << "通过桥的最小时间为: " << minTime << endl;

    return 0;
}

通过上述代码,我们可以实现对过桥问题的求解。编译并运行该程序后,你需要依次输入车辆数量、每辆车的重量以及桥的最大承载重量。程序会输出通过桥的最小时间。

请注意,上述代码是使用递归的方式求解过桥问题的,对于较大的测试用例可能会出现栈溢出的情况。为了避免这个问题,你可以尝试使用动态规划等其他方法来解决该问题。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^您好,我是有问必答小助手,您的问题已经有小伙伴帮您解答,感谢您对有问必答的支持与关注!
PS:问答VIP年卡 【限时加赠:IT技术图书免费领】,了解详情>>> https://vip.csdn.net/askvip?utm_source=1146287632