找到成本可以找到的最长距离的最佳方法

时间:2019-06-24 02:02:28

标签: algorithm graph-algorithm

假设您有一个顶点图。每个顶点到那里旅行都需要花费1美元,但是访问它也会获得比特币奖励。每个顶点都有一个相对于其他每个顶点以及自身的边缘。到给定顶点的成本是相同的,无论它是来自自身还是来自任何其他顶点。到给定顶点的奖励是相同的,无论是来自其本身还是来自任何其他顶点。示例:

顶点A:访问费用为$ 20,奖励为25比特币。

B点:访问费用为15美元,奖励为19个比特币。

顶点C:访问成本为6美元,奖励为7个比特币。

我可以用N美元在任何顶点开始。我想用我的美元获得尽可能多的比特币。如果我有$ 41,则在上面的示例中,我可以按任意顺序访问A,B,C一次,从而获得51个比特币。如果我有$ 40,则可以通过两次访问A获得50个比特币。

我已尝试通过暴力破解此问题

#include <iostream>
#include <tuple>
#include <iterator>
#include <list>
#include <vector>

struct vertex_t
{
    int dollar_cost = 0;
    int bitcoin_reward = 0;
};

int try_visit_vertex(int& dollars, const vertex_t& vertex)
{
    if (dollars >= vertex.dollar_cost)
    {
        dollars -= vertex.dollar_cost;
        return vertex.bitcoin_reward;
    }
    return 0; // couldn't visit
}

auto enumerateVertices(const std::tuple<int, int>& status, const std::vector<vertex_t>& vertices)
{
    std::list<std::tuple<int, int>> bitcoinsObtainedAndDollarsRemaining;
    for (auto& vertex : vertices)
    {
        auto dollars_remaining = std::get<1>(status);
        const auto bitcoinsObtained = try_visit_vertex(dollars_remaining, vertex);
        if (bitcoinsObtained)
            bitcoinsObtainedAndDollarsRemaining.push_back(std::make_tuple(std::get<0>(status) + bitcoinsObtained, dollars_remaining));
    }
    return bitcoinsObtainedAndDollarsRemaining;
}

int most_bitcoins(const int dollars, const std::vector<vertex_t>& vertices)
{
    int maxBitcoinsObtained = 0;
    std::list bitcoinsObtainedAndDollarsRemaining = { std::make_tuple(0, dollars) };
    while (!bitcoinsObtainedAndDollarsRemaining.empty())
    {
        auto& front = bitcoinsObtainedAndDollarsRemaining.front();
        maxBitcoinsObtained = std::max(maxBitcoinsObtained, std::get<0>(front));
        auto backOfQueue = enumerateVertices(front, vertices);
        bitcoinsObtainedAndDollarsRemaining.pop_front();
        bitcoinsObtainedAndDollarsRemaining.splice(std::end(bitcoinsObtainedAndDollarsRemaining), backOfQueue);
    }

    return maxBitcoinsObtained;
}

int main()
{
    std::cout << most_bitcoins(41, { { 20, 25 }, { 15, 19 }, { 6, 7 } });
}

我正在寻找更高效的人。我怀疑性能改进将是防止例如枚举时重复如果我push_back(A,A,B);我不应该后退(A,B,A)或(B,A,A)。甚至更好。。。不要压入任何重复的dollar_remaining + reward_amount元组。

0 个答案:

没有答案