c_cpp 计算站点之间的最低价格
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c_cpp 计算站点之间的最低价格相关的知识,希望对你有一定的参考价值。
// $ g++ minPrice3.cpp --std=c++11
//
// Ticket Prices:
//
// To
// | 0 | 1 | 2 | 3 | 4 |
// --+-----+-----+-----+-----+-----+
// 0 | 0 | 10 | 75 | 94 | 107 |
// F --+-----+-----+-----+-----+-----+
// r 1 | * | 0 | 35 | 50 | 83 |
// o --+-----+-----+-----+-----+-----+
// m 2 | * | * | 0 | 80 | 99 |
// --+-----+-----+-----+-----+-----+
// 3 | * | * | * | 0 | 10 |
// --+-----+-----+-----+-----+-----+
// 4 | * | * | * | * | 0 |
//
// Find the lowest price from station A to station B, where A <= B.
//
// Define LP(A, B) is the lowest price from A to B, then it could be
// calculated recursively by:
//
// LP(A, B) = Min(Price(A, B),
// LP(A, A+1) + Price(A+1, B),
// LP(A, A+2) + Price(A+2, B),
// ...
// LP(A, B-2) + Price(B-2, B))
// LP(A, B-1) + Price(B-1, B))
//
// Tips:
// If we know how to solve the lowest price from station 0 to station N
// then the lowest price from station A to station B is same as
// the solution from the lowest price from station 0 to station B-A.
#include <cassert>
#include <iostream>
#include <vector>
#undef RECURSION
#undef MEMOIZATION
#undef DYNAMIC_PROGRAMMING
#undef RUN
#define RECURSION 1
#define MEMOIZATION 2
#define DYNAMIC_PROGRAMMING 3
// #define RUN RECURSION
// #define RUN MEMOIZATION
// #define RUN DYNAMIC_PROGRAMMING
// Store all the ticket prices between the stations by a 2D vector.
std::vector< std::vector<int> > Price; // Ticket prices.
#if RUN == RECURSION
// Get lowest price from station 0 to station n
unsigned int
LowestPrice(unsigned int n, std::vector< std::vector<int> >& price)
{
assert(price.size() > n);
if (n == 0 || n == 1) {
return price[0][n];
}
// Assume the lowesr price is non-stop price.
unsigned int min = price[0][n];
// then compare it with stop
for (unsigned int stop = 1 ; stop < n ; ++stop) {
unsigned int cost = LowestPrice(stop, price) + price[stop][n];
if (cost < min) {
min = cost;
}
}
return min;
}
#elif RUN == MEMOIZATION
// Get lowest price from station 0 to station n
unsigned int
LowestPrice(unsigned int n,
std::vector< std::vector<int> >& price,
std::vector<int>& memo)
{
assert(price.size() > n && memo.size() >= n && price.size() >= memo.size());
if (n == 0 || n == 1) {
return price[0][n];
}
if (memo[n] < 0) {
// Assume the lowesr price is non-stop price.
unsigned int min = price[0][n];
// then compare it with stop
for (unsigned int stop = 1 ; stop < n ; ++stop) {
unsigned int cost = LowestPrice(stop, price, memo) + price[stop][n];
if (cost < min) {
min = cost;
}
}
memo[n] = min;
}
return memo[n];
}
// Get lowest price from station 0 to station n
unsigned int
LowestPrice(unsigned int n, std::vector< std::vector<int> >& price)
{
assert(price.size() > n);
std::vector<int> memo(price.size(), -1);
return LowestPrice(n, price, memo);
}
#else // RUN == DYNAMIC_PROGRAMMING
// Get lowest price from station 0 to station n
unsigned int
LowestPrice(unsigned int n, std::vector< std::vector<int> >& price)
{
assert(price.size() > n);
std::vector<int> lp(n+1, -1);
// LP(0, 0) = Price(0, 0), LP(0, 1) = Price(0, 1)
lp[0] = price[0][0];
if (lp.size() > 1) {
lp[1] = price[0][1];
}
for (unsigned int i = 2 ; i <= n ; ++i) {
// Assume the lowest price from 0 to i is the non-stop price first.
lp[i] = price[0][i];
for (unsigned int stop = 1 ; stop < n ; ++stop) {
unsigned int cost = lp[stop] + price[stop][i];
if (cost < lp[i]) {
lp[i] = cost;
}
}
}
assert(lp[n] != -1);
return lp[n];
}
#endif
// Get partial price table from station start to destination
std::vector< std::vector<int> >
GetPrice(unsigned int start, unsigned int destination)
{
const unsigned int size = destination - start + 1;
std::vector<std::vector<int>>
offsetPrice(size, std::vector<int>(size, -1));
for (unsigned int i = 0 ; i < offsetPrice.size() ; ++i) {
for (unsigned int j = i ; j < offsetPrice.size() ; ++j) {
offsetPrice[i][j] = Price[start + i][start + j];
}
}
return offsetPrice;
}
// Get lowest price from station start to station destination
unsigned int
LowestPrice(unsigned int start, unsigned int destination)
{
assert(start <= destination);
assert(Price.size() > start && Price[0].size() > destination);
std::vector< std::vector<int> > offsetPrice = GetPrice(start, destination);
return LowestPrice(destination - start, offsetPrice);
}
int main()
{
Price = {
{ 0, 10, 75, 94, 107 },
{ -1, 0, 35, 50, 83 },
{ -1, -1, 0, 80, 99 },
{ -1, -1, -1, 0, 10 },
{ -1, -1, -1, -1, 0 },
};
unsigned int start = 1;
unsigned int dest = 4;
unsigned int cost = LowestPrice(start, dest);
std::cout << "Lowest price from " << start << " to " <<
dest << " is " << cost << std::endl;
return 0;
}
// $ g++ minPrice2.cpp --std=c++11
//
// Ticket Prices:
//
// To
// | 0 | 1 | 2 | 3 | 4 |
// --+-----+-----+-----+-----+-----+
// 0 | 0 | 10 | 75 | 94 | 107 |
// F --+-----+-----+-----+-----+-----+
// r 1 | * | 0 | 35 | 50 | 83 |
// o --+-----+-----+-----+-----+-----+
// m 2 | * | * | 0 | 80 | 99 |
// --+-----+-----+-----+-----+-----+
// 3 | * | * | * | 0 | 10 |
// --+-----+-----+-----+-----+-----+
// 4 | * | * | * | * | 0 |
//
// Find the lowest price from station A to station B, where A <= B.
//
// Define LP(A, B) is the lowest price from A to B, then it could be
// calculated recursively by:
//
// LP(A, B) = Min(Price(A, B),
// LP(A, A+1) + Price(A+1, B),
// LP(A, A+2) + Price(A+2, B),
// ...
// LP(A, B-2) + Price(B-2, B))
// LP(A, B-1) + Price(B-1, B))
#include <cassert>
#include <iostream>
#include <vector>
#undef RECURSION
#undef MEMOIZATION
#undef DYNAMIC_PROGRAMMING
#undef RUN
#define RECURSION 1
#define MEMOIZATION 2
#define DYNAMIC_PROGRAMMING 3
// #define RUN RECURSION
// #define RUN MEMOIZATION
// #define RUN DYNAMIC_PROGRAMMING
// Store all the ticket prices between the stations by a 2D vector.
std::vector< std::vector<int> > Price; // Ticket prices.
#if RUN == RECURSION
unsigned int
LowestPrice(unsigned int start, unsigned int destination)
{
assert(start <= destination);
assert(Price.size() > start && Price[0].size() > destination);
if (start == destination || start + 1 == destination) {
return Price[start][destination];
}
unsigned int min = Price[start][destination];
for (unsigned int stop = start + 1 ; stop < destination ; ++stop) {
unsigned int cost = LowestPrice(start, stop) + Price[stop][destination];
if (cost < min) {
min = cost;
}
}
return min;
}
#elif RUN == MEMOIZATION
unsigned int
LowestPriceWithMemo(unsigned int start,
unsigned int destination,
std::vector<std::vector<int>>& memo)
{
assert(start <= destination);
assert(Price.size() > start && Price[0].size() > destination);
if (start == destination || start + 1 == destination) {
return Price[start][destination];
}
if (memo[start][destination] < 0) {
unsigned int min = Price[start][destination];
for (unsigned int stop = start + 1 ; stop < destination ; ++stop) {
unsigned int cost = LowestPrice(start, stop) + Price[stop][destination];
if (cost < min) {
min = cost;
}
}
memo[start][destination] = min;
}
assert(memo[start][destination] != -1);
return memo[start][destination];
}
unsigned int
LowestPrice(unsigned int start, unsigned int destination)
{
assert(start <= destination);
assert(Price.size() > start && Price[0].size() > destination);
// Store the lowest prices between the stations by a 2D vector.
std::vector<std::vector<int>>
memo(Price.size(), std::vector<int>(Price[0].size(), -1));
// Actually, we could only use a (dest-start+1)^2 table to save
// all the lowest prices, but we need to use memo[a-offset][b-offset]
// instead of memo[a][b] to record the lowest price from station a to b,
// where offset = start here.
return LowestPriceWithMemo(start, destination, memo);
}
#else // RUN == DYNAMIC_PROGRAMMING
// unsigned int
// LowestPrice(unsigned int start, unsigned int destination)
// {
// assert(start <= destination);
// assert(Price.size() > start && Price[0].size() > destination);
// // Store the lowest prices between the stations from start to each station.
// std::vector<int> lp(Price.size(), -1);
// // Actually, we only need `destination-start+1` size vector here.
// lp[start] = Price[start][start];
// if (start + 1 < lp.size()) {
// lp[start + 1] = Price[start][start + 1];
// }
// const unsigned int distance = destination - start;
// for (unsigned int d = 2 ; d <= distance ; ++d) {
// unsigned int last = start + d;
// if (last > lp.size() - 1) {
// break;
// }
// // Assume the lowest price is the non-stop price first.
// lp[last] = Price[start][last];
// for (unsigned int j = 1 ; j < d ; ++j) {
// unsigned int stop = start + j;
// unsigned int cost = lp[stop] + Price[stop][last];
// if (cost < lp[last]) {
// lp[last] = cost;
// }
// }
// }
// assert(lp[distance] != -1);
// return lp[destination];
// }
unsigned int LowestPrice(unsigned int start, unsigned int destination)
{
assert(start <= destination);
assert(Price.size() > start && Price[0].size() > destination);
// Store the lowest prices between the stations from start to each station.
const unsigned int distance = destination - start;
const unsigned int size = distance + 1;
// lp[x] = lowest prices from start to start+x.
std::vector<int> lp(size, -1);
// LP(start, start) = Price(start, start),
// LP(start, start+1) = Price(start, start+1)
lp[0] = Price[start][start];
if (1 < lp.size()) {
lp[1] = Price[start][start + 1];
}
for (unsigned int d = 2 ; d <= distance ; ++d) {
// Assume the lowest price is the non-stop price first.
unsigned int last = start + d;
lp[d] = Price[start][last];
for (unsigned int j = 1 ; j < d ; ++j) {
unsigned int stop = start+j;
unsigned int cost = lp[j] + Price[stop][last];
if (cost < lp[d]) {
lp[d] = cost;
}
}
}
assert(lp[distance] != -1);
return lp[distance];
}
#endif
int main()
{
Price = {
{ 0, 10, 75, 94, 107 },
{ -1, 0, 35, 50, 83 },
{ -1, -1, 0, 80, 99 },
{ -1, -1, -1, 0, 10 },
{ -1, -1, -1, -1, 0 },
};
unsigned int start = 1;
unsigned int dest = 4;
unsigned int cost = LowestPrice(start, dest);
std::cout << "Lowest price from " << start << " to " <<
dest << " is " << cost << std::endl;
return 0;
}
// $ g++ minPrice1.cpp --std=c++11
//
// Ticket Prices:
//
// To
// | 0 | 1 | 2 | 3 | 4 |
// --+-----+-----+-----+-----+-----+
// 0 | 0 | 10 | 75 | 94 | 107 |
// F --+-----+-----+-----+-----+-----+
// r 1 | * | 0 | 35 | 50 | 83 |
// o --+-----+-----+-----+-----+-----+
// m 2 | * | * | 0 | 80 | 99 |
// --+-----+-----+-----+-----+-----+
// 3 | * | * | * | 0 | 10 |
// --+-----+-----+-----+-----+-----+
// 4 | * | * | * | * | 0 |
//
// Find the lowest price from station A to station B, where A <= B.
//
// Define LP(A, B) is the lowest price from A to B, then it could be
// calculated recursively by:
//
// LP(A, B) = Min(Price(A, B),
// LP(A, A+1) + LP(A+1, B),
// LP(A, A+2) + LP(A+2, B),
// ...
// LP(A, B-2) + LP(B-2, B))
// LP(A, B-1) + LP(B-1, B))
#include <cassert>
#include <iostream>
#include <vector>
#undef RECURSION
#undef MEMOIZATION
#undef DYNAMIC_PROGRAMMING
#undef RUN
#define RECURSION 1
#define MEMOIZATION 2
#define DYNAMIC_PROGRAMMING 3
// #define RUN RECURSION
// #define RUN MEMOIZATION
#define RUN DYNAMIC_PROGRAMMING
// Store all the ticket prices between the stations by a 2D vector.
std::vector< std::vector<int> > Price; // Ticket prices.
#if RUN == RECURSION
unsigned int
LowestPrice(unsigned int start, unsigned int destination)
{
assert(start <= destination);
assert(Price.size() > start && Price[0].size() > destination);
if (start == destination || start + 1 == destination) {
return Price[start][destination];
}
unsigned int min = Price[start][destination];
for (unsigned int stop = start + 1 ; stop < destination ; ++stop) {
unsigned int cost = LowestPrice(start, stop) +
LowestPrice(stop, destination);
if (cost < min) {
min = cost;
}
}
return min;
}
#elif RUN == MEMOIZATION
unsigned int
LowestPriceWithMemo(unsigned int start,
unsigned int destination,
std::vector<std::vector<int>>& memo)
{
assert(start <= destination);
assert(Price.size() > start && Price[0].size() > destination);
if (start == destination || start + 1 == destination) {
// memo[start][destination] = Price[start][destination];
return Price[start][destination];
}
if (memo[start][destination] < 0) {
unsigned int min = Price[start][destination];
for (unsigned int stop = start + 1 ; stop < destination ; ++stop) {
unsigned int cost = LowestPriceWithMemo(start, stop, memo) +
LowestPriceWithMemo(stop, destination, memo);
if (cost < min) {
min = cost;
}
}
memo[start][destination] = min;
}
assert(memo[start][destination] != -1);
return memo[start][destination];
}
unsigned int
LowestPrice(unsigned int start, unsigned int destination)
{
assert(start <= destination);
assert(Price.size() > start && Price[0].size() > destination);
// Store the lowest prices between the stations by a 2D vector.
std::vector<std::vector<int>>
memo(Price.size(), std::vector<int>(Price[0].size(), -1));
// Actually, we could only use a (dest-start+1)^2 table to save
// all the lowest prices, but we need to use memo[a-offset][b-offset]
// instead of memo[a][b] to record the lowest price from station a to b,
// where offset = start here.
return LowestPriceWithMemo(start, destination, memo);
}
#else // RUN == DYNAMIC_PROGRAMMING
// unsigned int
// LowestPrice(unsigned int start, unsigned int destination)
// {
// assert(start <= destination);
// assert(Price.size() > start && Price[0].size() > destination);
// // Store the lowest prices between the stations by a 2D vector.
// // lp[i][j] = minimal distance from i to j.
// std::vector<std::vector<int>>
// lp(Price.size(), std::vector<int>(Price[0].size(), -1));
// // Actually, we could only use a (dest-start+1)^2 table to save
// // all the lowest prices.
// // LP(a, b) = Price(a, b) if b = a or b = a + 1.
// for (unsigned int i = 0 ; i < lp.size() ; ++i) {
// lp[i][i] = Price[i][i];
// if (i + 1 < lp[i].size()) {
// lp[i][i + 1] = Price[i][i + 1];
// }
// }
// const unsigned int distance = destination - start;
// for (unsigned int d = 2 ; d <= distance ; ++d) {
// for (unsigned int i = 0 ; i < lp.size() ; ++i) {
// unsigned int last = i + d;
// if (last > lp.size() - 1) {
// break;
// }
// // Assume the minimal price from state i to last is the non-stop price.
// lp[i][last] = Price[i][last];
// // Iteratively check the minimal price.
// for (unsigned int j = 1 ; j < d ; ++j) {
// unsigned int stop = i + j;
// unsigned int cost = lp[i][stop] + lp[stop][last];
// if (lp[i][last] > cost) {
// lp[i][last] = cost;
// }
// }
// }
// }
// assert(lp[start][destination] != -1);
// return lp[start][destination];
// }
// unsigned int
// LowestPrice(unsigned int start, unsigned int destination)
// {
// assert(start <= destination);
// assert(Price.size() > start && Price[0].size() > destination);
// // Store the lowest prices between the stations by a 2D vector.
// // lp[i][j] = minimal distance from i to j.
// std::vector<std::vector<int>>
// lp(Price.size(), std::vector<int>(Price[0].size(), -1));
// // Actually, we could only use a (dest-start+1)^2 table to save
// // all the lowest prices.
// // Assume the minimal price from state start+i
// // to start+farmost is the non-stop price.
// for (unsigned int i = 0 ; i < lp.size() ; ++i) {
// for (unsigned int j = i ; j < lp[i].size() ; ++j) {
// lp[i][j] = Price[i][j];
// }
// }
// // LP(a, b) = Price(a, b) if b = a or b = a + 1,
// // so we don't need to check the
// // prices between stations whose distance is 0 or 1.
// const unsigned int distance = destination - start;
// for (unsigned int d = 2 ; d <= distance ; ++d) {
// for (unsigned int i = 0 ; i < lp.size() ; ++i) {
// unsigned int last = i + d;
// if (last > lp.size() - 1) {
// break;
// }
// // Iteratively check the minimal price.
// for (unsigned int j = 1 ; j < d ; ++j) {
// unsigned int stop = i + j;
// unsigned int cost = lp[i][stop] + lp[stop][last];
// if (lp[i][last] > cost) {
// lp[i][last] = cost;
// }
// }
// }
// }
// assert(lp[start][destination] != -1);
// return lp[start][destination];
// }
// unsigned int
// LowestPrice(unsigned int start, unsigned int destination)
// {
// assert(start <= destination);
// assert(Price.size() > start && Price[0].size() > destination);
// // Store the lowest prices between the stations by a 2D vector.
// // lp[i][j] = minimal distance from start+i to start+j
// const unsigned int distance = destination - start;
// const unsigned int size = distance + 1;
// std::vector<std::vector<int>>
// lp(size, std::vector<int>(size, -1));
// // LP(a, b) = Price(a, b) if b = a or b = a + 1.
// for (unsigned int i = 0 ; i < lp.size() ; ++i) {
// lp[i][i] = Price[start+i][start+i];
// if (i + 1 < lp[i].size()) {
// lp[i][i + 1] = Price[start + i][start + i + 1];
// }
// }
// for (unsigned int d = 2 ; d <= distance ; ++d) {
// for (unsigned int i = 0 ; i < lp.size() ; ++i) {
// unsigned int farmost = i + d;
// if (farmost > lp.size() - 1) {
// break;
// }
// // Assume the minimal price from state start+i
// // to start+farmost is the non-stop price.
// lp[i][farmost] = Price[start + i][start + farmost];
// // Iteratively check the minimal price.
// for (unsigned int j = 1 ; j < d ; ++j) {
// unsigned int stop = i + j;
// unsigned int cost = lp[i][stop] + lp[stop][farmost];
// if (lp[i][farmost] > cost) {
// lp[i][farmost] = cost;
// }
// }
// }
// }
// assert(lp[0][distance] != -1);
// return lp[0][distance];
// }
unsigned int
LowestPrice(unsigned int start, unsigned int destination)
{
assert(start <= destination);
assert(Price.size() > start && Price[0].size() > destination);
// Store the lowest prices between the stations by a 2D vector.
// lp[i][j] = minimal distance from start+i to start+j
const unsigned int distance = destination - start;
const unsigned int size = distance + 1;
std::vector<std::vector<int>>
lp(size, std::vector<int>(size, -1));
// Assume the minimal price from state start+i
// to start+farmost is the non-stop price.
for (unsigned int i = 0 ; i < lp.size() ; ++i) {
for (unsigned int j = i ; j < lp[i].size() ; ++j) {
lp[i][j] = Price[start + i][start + j];
}
}
// LP(a, b) = Price(a, b) if b = a or b = a + 1,
// so we don't need to check the prices between
// stations whose distance is 0 or 1.
for (unsigned int d = 2 ; d <= distance ; ++d) {
for (unsigned int i = 0 ; i < lp.size() ; ++i) {
unsigned int farmost = i + d;
if (farmost > lp.size() - 1) {
break;
}
// Iteratively check the minimal price.
for (unsigned int j = 1 ; j < d ; ++j) {
unsigned int stop = i + j;
unsigned int cost = lp[i][stop] + lp[stop][farmost];
if (lp[i][farmost] > cost) {
lp[i][farmost] = cost;
}
}
}
}
assert(lp[0][distance] != -1);
return lp[0][distance];
}
#endif
int main()
{
Price = {
{ 0, 10, 75, 94, 107 },
{ -1, 0, 35, 50, 83 },
{ -1, -1, 0, 80, 99 },
{ -1, -1, -1, 0, 10 },
{ -1, -1, -1, -1, 0 },
};
unsigned int start = 1;
unsigned int dest = 4;
unsigned int cost = LowestPrice(start, dest);
std::cout << "Lowest price from " << start << " to " <<
dest << " is " << cost << std::endl;
return 0;
}
以上是关于c_cpp 计算站点之间的最低价格的主要内容,如果未能解决你的问题,请参考以下文章