【问题标题】:Knapsack DP How to find total number of value taken?背包 DP 如何求取值的总数?
【发布时间】:2011-12-16 17:26:56
【问题描述】:

好像

最大重量 3

Value Weight 

1955    1
2000    5
101     1

拿第一和第三。但找不到总价值。 1955+101。

我使用背包 0-1。有没有办法从数组中找到1955+101

【问题讨论】:

  • 当然,您必须通过 DP 矩阵回溯并重建选择。网上有大量的描述。缺点是您需要保留整个矩阵;如果您不想这样做,您可以通过只保留一小部分数据来节省空间。
  • 你能告诉我算法吗?我尝试搜索但没有找到
  • 不是在我的脑海中,但如果你愿意,请自己考虑......它应该是显而易见的事情。否则尝试维基百科;我很确定有它(至少关于最长公共子序列的文章有类似的代码)。
  • @zeulb this question 展示了如何从构造的矩阵中找到为您提供背包问题最佳解决方案的确切元素。

标签: c++ algorithm dynamic-programming knapsack-problem


【解决方案1】:

假设您有 2 个数组 valueswt,以及另一个变量 initial_capacity 这是背包的最大容量。然后,您需要先调用 dp 函数,该函数计算您可以实现的 maxValuereconstruct 函数会告诉您应该采取哪些物品才能达到 maxValue。

int dp(int position, int weight)
{
    if(position == no_of_items) return 0;
    if(mem[position][weight] != -1) return mem[position][weight];

    int r1 = dp(position + 1, weight);
    int r2 = dp(position + 1, weight - wt[position]) + value[position];

    return mem[position][weight] = max(r1, r2);
}

void reconstruct(int position, int weight)
{
    if(position == no_of_items) return;

    int r1 = dp(position + 1, weight);
    int r2 = dp(position + 1, weight - wt[position]) + value[position];

    if(r2 > r1)
    {
        cout << "Take item at position : " << position << endl;
        reconstruct(position + 1, weight - wt[position]);
    }
    else
    {
        reconstruct(position + 1, weight);
    }
}

int main()
{
    //read input here
    memset(mem, -1);
    int maxValue = dp(0, initial_capacity);
    cout << "Max value : " << maxValue << endl;
    reconstruct(0, initial_capacity);
}

请注意,重构以贪婪的方式工作。哪个决定(接受该项目或跳过该项目)会导致 maxValue,它将做出该决定。如果您的决定涉及获取特定项目,则打印该项目的索引。

希望这会有所帮助:)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-28
    • 2016-12-25
    • 1970-01-01
    相关资源
    最近更新 更多