问题描述:
小R正在计划一次从地点A到地点B的徒步旅行,总路程需要 N
天。为了在旅途中保持充足的能量,小R每天必须消耗1份食物。幸运的是,小R在路途中每天都会经过一个补给站,可以先购买完食物后再消耗今天的1份食物。然而,每个补给站的食物每份的价格可能不同,并且小R在购买完食物后最多只能同时携带 K
份食物。
现在,小R希望在保证每天食物消耗的前提下,以最小的花费完成这次徒步旅行。你能帮助小R计算出最低的花费是多少吗?
**输入 **
n
总路程需要的天数k
小R最多能同时携带食物的份数data[i]
第i天补给站每份食物的价格
**输出 **
- 返回完成这次徒步旅行的最小花费
**约束条件 **
1
<n,k
<1000
1
<data[i]
<10000
#include <algorithm>
#include <climits>
#include <iostream>
#include <vector>
using namespace std;
int solution(int n, int k, vector<int> data) {
// 创建动态规划二维数组,dp[i][j]表示前i天,剩余j份食物时的最小花费
vector<vector<int>> dp(n + 1, vector<int>(k + 1, INT_MAX));
dp[0][0] = 0;
// 遍历每一天
for (int i = 0; i < n; i++) {
// 遍历当天结束后剩余食物的份数情况
for (int j = 0; j <= k; ++j) {
if (dp[i][j] == INT_MAX)
continue;
// 不购买只消耗一份食物(前提是还有食物可消耗,即j > 0)
if (j > 0) {
dp[i + 1][j - 1] = min(dp[i + 1][j - 1], dp[i][j]);
}
// 尝试购买不同数量的食物x份
for (int x = 1; x <= k - j; x++) {
if (j + x <= k) {
dp[i + 1][j + x - 1] =
min(dp[i + 1][j + x - 1], dp[i][j] + x * data[i]);
}
}
}
}
return dp[n][0];
}
int main() {
// Add your test cases here
std::cout << (solution(5, 2, {1, 2, 3, 3, 2}) == 9) << std::endl;
return 0;
}
该问题可以用动态规划来解决,dp[i][j] 表示在第i天还剩余j食物所花费最少的费用。
在初始化的过程中生成 dp数组行为n+1,列为k+1的dp数组。初始化为无穷。
状态定义:
采用不购买消耗现有食物的策略,需要食物的数量大于等于1(j>=1)
dp[i+1][j-1] = min(dp[i][j], dp[i+1][j-1]);
另一种策略在当前节点购买x份食物,约束条件为(j+x <= k)表示为当前可以购买的食物x份:对于该策略
dp[i+1][j-1+x] = min(dp[i+1][j-1+x] , dp[i][j] + x*data[i]);
最后输出的结果记为到达最后一天且没有食物剩余的最小的花费对应的花费可以表示为dp[n][0].