选择可能的总和填充物

时间:2017-10-25 08:41:52

标签: c++ algorithm

所以我必须编写一个程序,其中用户应该输入某种包装重量和距离,以便使用用户输入的值发送3种类型的邮戳,并且必须打印出每种可能的组合在包装上贴上标记。通常,我对组合算法没有任何问题,但我不认为这与组合学有关,因为数字的值很重要。我一直想着好几个小时都无法解决任何问题。这是我的来源,仅用于我的功能。

float weight,price,total_price,m1,m2,m3;
int zone;

system("cls");

cout<<"Input package weight: ";
cin>>weight;

    if (weight<0 && weight>10) error();

   else if (weight<1) price=20;
   else if (weight<2) price=35;
   else if (weight<5) price=70;
   else price=120;

system("cls");

cout<<"Input zone(1/2/3): ";
cin>>zone;

    switch(zone)
    {
        case 1: total_price=price*1;    break;
        case 2: total_price=price*1.2;  break;
        case 3: total_price=price*1.5;  break;
        default: error();

system("cls");

cout<<"Input your mark price(1/3): ";
cin>>m1;
system("cls");
cout<<"Input your mark price(2/3): ";
cin>>m2;
system("cls");
cout<<"Input your mark price(3/3): ";
cin>>m3;

output();

1 个答案:

答案 0 :(得分:0)

我没有一种有效的方法来获得理想的结果(我仍在学习算法的基础知识:)),但我相信以下方法可以解决问题。

让我们开始吧。 如果要求只有两枚邮票,

  • 找出两个邮票价格中的最大值,并将总费用除以 这个(取值作为size_t去除小数部分)。这个 返回可以使用更昂贵的图章的总时间 发送包裹。
  • 现在从0迭代到此计数。迭代 index表示使用的更昂贵的邮票数量。找出 我们必须使用更便宜的邮票的剩余金额。要是我们 可以用更便宜的邮票完美地划分剩余金额( fmod(diff,price_of_cheaper_stamp)),我们有一个设置 我们需要。那就是(iteration_index,diff / price_of_cheaper_stamp)。
  • 继续迭代以找到剩余的集合。

代码如下:

std::vector< std::pair< std::size_t, std::size_t > >
GetCombinations( double inTotal, double inM1, double inM2 )
{
    std::vector< std::pair< std::size_t, std::size_t > > result;
    auto maxVal = std::max( inM1, inM2 );
    auto minVal = std::min( inM1, inM2 );
    std::size_t maxCount = inTotal / maxVal;
    for( std::size_t i = 0; i <= maxCount; ++i )
    {
        auto diff = inTotal - ( maxVal * i );
        if( fmod(diff, minVal) == 0 )
        {
            result.emplace_back( i, diff / minVal );
        }
    }
    return result;
}

我们现在可以将其扩展为具有三个标记方案。

  • 我们将采用成本最高的邮票的价格。找到最大数量 我们可以使用那张邮票。
  • 然后从0迭代到计数,并且对于数量的差异 需要用更便宜的邮票补偿,计算 使用前一种方法的组合。

代码如下:

struct Set
{
    std::size_t x;  // count of costliest stamp
    std::size_t y;
    std::size_t z;  // count of cheapest stamp
};

std::vector< Set >
GetCombinations( double inTotal, double inM1, double inM2, double inM3 )
{
    std::vector< Set > result;
    auto maxVal = std::max( inM1, std::max( inM2, inM3 ) );
    std::size_t maxCount = inTotal/maxVal;

    // Find the prices of cheaper stamps.
    auto m1 = std::min( inM1, inM2 );
    auto m2 = std::min( inM2, inM3 );
    for( std::size_t i=0; i <= maxCount; ++i )
    {
        auto diff = inTotal - ( maxVal * i );
        auto subCombinations = GetCombinations( diff, m1, m2 );
        for( auto const & subComb : subCombinations )
        {
            result.push_back( Set{ i, 0, 0 } );
            result.back().y = subComb.first;
            result.back().z = subComb.second;
        }
    }
    return result;
}

您可以在https://ideone.com/OkIDKK

中找到完整的代码