算法导论 第三版, 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;
}