rod_cutting, introduction to algorithm 3rd, example 15.1

算法导论 第三版, 15.1动态规划问题的实现

// introduction to algorithm 3rd, example 15.1

#include <iostream>
#include <vector>
#include <algorithm>
#include <cassert>
#include "stopwatch.h"

static int price_table[] =
{
    1, 5, 8, 9, 10, 17, 17, 20, 24, 30
};

static int price_table_size = sizeof(price_table) /sizeof(int);

struct Split
{
    Split() : price(-1), left(0), right(0) {}
    int price;
    int left;
    int right;
};

// recursive version
int max_price(int rod_length, std::vector<Split> & splits)
{
    if (rod_length == 0)
    {
        return 0;
    }

    if (splits.at(rod_length-1).price > 0)
    {
        return splits.at(rod_length-1).price;
    }

    int price = 0;
    for ( int i = 0; i < std::min(rod_length, price_table_size); ++i)
    {
        int sub_price = price_table[i] + max_price(rod_length-i-1, splits);
        if (price < sub_price)
        {
            price = sub_price;
            splits.at(rod_length-1).left = i+1;
            splits.at(rod_length-1).right = rod_length-i-1;
            splits.at(rod_length-1).price = price;
        }
    }

    return price;
}

// none-recursive version
int max_price2(int rod_length, std::vector<Split> & splits)
{
    for (int i = 0; i < rod_length; ++i)
    {
        int price = 0;
        for (int k = 0; k < std::min(i+1, price_table_size); ++k)
        {
            int subprice = price_table[k];
            if (k != i)
            {
                subprice += splits.at(i-k-1).price;
            }
            if (price < subprice)
            {
                price = subprice;
                splits.at(i).price = price;
                splits.at(i).left = k+1;
                splits.at(i).right = i-k;
            }
        }
    }
    return splits.at(rod_length-1).price;
}

void print_solution(const std::vector<Split> & splits, int rod_length)
{
    std::cout << splits.at(rod_length-1).left << ' ';
    if (splits.at(rod_length-1).right > 0)
    {
        print_solution(splits, splits.at(rod_length-1).right);
    }
}

void cut_rod(int length)
{
    Stopwatch watch;
    watch.start();
    std::vector<Split> splits(length);
    int price = max_price(length, splits);
    watch.stop();
    std::cout << "cut_rod:\n";
    std::cout << "max price for rod has length " << length << " is " << price << " use time " << watch.elapsed() << " ms" << std::endl;
    std::cout << "the solution is : \n";
    print_solution(splits, length);
    std::cout << std::endl;
}

void cut_rod_recursive(int length)
{
    Stopwatch watch;
    watch.start();
    std::vector<Split> splits(length);
    int price = max_price2(length, splits);
    watch.stop();
    std::cout << "cut_rod_recursive:\n";
    std::cout << "max price for rod has length " << length << " is " << price << " use time " << watch.elapsed() << " ms" << std::endl;
    std::cout << "the solution is : \n";
    print_solution(splits, length);
    std::cout << std::endl;
}

int main()
{
    std::cout << "start" << std::endl;
    int len = 5876;
    cut_rod(len);
    cut_rod_recursive(len);
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值