购买有限货币的物品的算法

时间:2014-09-26 11:40:56

标签: c++ algorithm

我有X钱购买价格为Y [](最多30件商品)的商品,一件商品只能购买一次。 获得您可以花费的最高金额。

  

例如的   
输入:   
钱:24   
项目数量:5   
项目价格:7,7,7,5,5   
  
产出:最高花钱:24(7 + 7 + 5 + 5)

实现这一目标的最佳算法是什么? 我试图制作代码,但似乎非常不理想

#include <iostream>

using namespace std;

int main()
{
    int X;
    cout << "money: ";
    cin >> X;

    int Y[30]; //max 30 items

    int amount; //item amount
    cout << "amount of items: ";
    cin >> amount;

    cout << "item price: ";
    for(int i=1; i<=amount; i++)
    {
        cin >> Y[i];
    }

    //sort the price
    bool sort = true;
    while (sort == true)
    {
        int temp;
        sort = false;
        for(int x=amount; x>=2; x--)
        {
            if(Y[x] < Y[x-1])
            {
                temp = Y[x];
                Y[x] = Y[x-1];
                Y[x-1] = temp;
                sort = true;
            }
        }
    }

    int priceTotal = 0;
    int moneyLeft = X;
    int maxMoneySpend = 0;

    for(int j=0; j<=amount; j++)
    {
        priceTotal = 0;
        moneyLeft = X;
        for(int i=amount-j; i>=1; i--)
           if(moneyLeft - Y[i] >= 0)
           {
                moneyLeft -= Y[i];
                priceTotal += Y[i];
            }
        }
        if (maxMoneySpend < priceTotal)
        {
            maxMoneySpend = priceTotal;
        }
    }

    cout << "maximum money spend: " << maxMoneySpend << endl;
    return 0;
}

2 个答案:

答案 0 :(得分:1)

此问题可归类为经典的0/1背包问题。您可以使用以下递归实现来执行此任务。虽然这有重叠的子问题。 因此,解决它的最佳方法是使用DP(动态编程)。

typedef long long ll;

ll knapsack(ll id, ll a[], ll desiredVal) // array a[] contains the values ....  
{
    if(desiredVal<=0 || id<0)
        return 0;

    if(a[id]>desiredVal)
        return knapsack(id-1,a,desiredVal);

    else {
        ll s1 = a[id] + knapsack(id-1,a,desiredVal-a[id]); // taken the weight //
        ll s2 = knapsack(id-1,a,desiredVal); // Not taken the weight //

        return max(s1,s2);
    }

}

从main函数中,您可以调用此方法,如下所示:

knapsack(No_Item-1,a,desiredVal); 
// Like in your exm : No_Item -> 5 , a[]={7,7,7,5,5}, desiredVal -> 24 

答案 1 :(得分:0)

正如其他人所指出的,这个问题是NP完全的,因此没有有效的解决方案。你的情绪甚至很快,但不幸的是不正确。

你总是从廉价到昂贵的元素。假设你有元素(10,4,4,2,1)和9的数量。你永远不会最终选择4,4,1,这非常适合。原因是你只会在第一个循环中取1.但没有1,你就不能得到一个奇数(所有其他都是偶数)。取1后,你将加上2和4,共7。接下来的4个不合适。当你先拿4分时,你可以选择接下来的4分,但是8分。但是不会达到9分。

无论如何,由于Y的基数最高为30,因此您无法找到最优解的算法。 30对于今天的计算机来说太大了。最佳解决方案是采用Y的所有子集(称为Y的幂集),计算每个成本,并采用其中最昂贵的成本。 30个项目的子集太多了。它可能适用于20个项目。你不能比这更有效率。