C++且不使用vector头文件完成:最厉害的加勒比海盗杰克船长驾驶着他的黑珍珠号海盗船找到了一个装满宝藏的藏宝洞。藏宝洞里面有 NN≤100 堆金币第 i堆金币的总重量和总价值分别是 mivi1≤mivi≤100。黑珍珠号的承重量为 TT≤1000。为了长远发展所以他决定带走尽可能少价值的金币但是他要求必须装满。所有金币都可以随意分割分割完的金币重量价值比也就是单位价值不变。请问杰克船长最少可以
该问题可以使用动态规划来解决。我们定义一个二维数组dp,其中dp[i][j]表示在前i堆金币中选择总重量不超过j的情况下,能够得到的最小总价值。
初始状态为dp[0][j] = 0,表示没有金币可选时,总价值为0。对于其他状态dp[i][j],可以通过以下方式进行更新:
- 如果第i堆金币的重量mi大于j,即无法选择第i堆金币,则dp[i][j] = dp[i-1][j],即等于前i-1堆金币在总重量不超过j的情况下的最小总价值;
- 如果第i堆金币的重量mi小于等于j,可以选择第i堆金币或不选择第i堆金币。如果选择第i堆金币,则dp[i][j] = dp[i-1][j-mi] + vi,即等于前i-1堆金币在总重量不超过j-mi的情况下的最小总价值加上第i堆金币的价值vi;如果不选择第i堆金币,则dp[i][j] = dp[i-1][j],即等于前i-1堆金币在总重量不超过j的情况下的最小总价值。
最终的答案即为dp[N][T],表示在前N堆金币中选择总重量不超过T的情况下,能够得到的最小总价值。
下面是使用C++代码实现该算法:
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
int N, T;
cin >> N >> T;
int m[N+1], v[N+1];
for (int i = 1; i <= N; i++) {
cin >> m[i] >> v[i];
}
double dp[N+1][T+1];
for (int i = 0; i <= N; i++) {
for (int j = 0; j <= T; j++) {
if (i == 0 || j == 0) {
dp[i][j] = 0;
} else if (m[i] > j) {
dp[i][j] = dp[i-1][j];
} else {
dp[i][j] = max(dp[i-1][j], dp[i-1][j-m[i]] + v[i]);
}
}
}
cout << fixed << setprecision(2) << dp[N][T] << endl;
return 0;
}
注意,为了保留两位小数,我们使用了fixed和setprecision函数来设置输出格式
原文地址: http://www.cveoy.top/t/topic/h36o 著作权归作者所有。请勿转载和采集!