阿里巴巴走进了装满宝藏的藏宝洞。藏宝洞里面有 N(N \le 100)N(N≤100) 堆金币,第 ii 堆金币的总重量和总价值分别是 m_i,v_i(1\le m_i,v_i \le 100)m i ,v i (1≤m i ,v i ≤100)。阿里巴巴有一个承重量为 T(T \le 1000)T(T≤1000) 的背包,但并不一定有办法将全部的金币都装进去。他想装走尽可能多价值的金币。所有金币都可以随意分割,分割完的金币重量价值比(也就是单位价格)不变。请问阿里巴巴最多可以拿走多少价值的金币?(C语言)
时间: 2024-02-17 17:02:16 浏览: 123
这是一道经典的背包问题,可以使用动态规划来解决。
定义 dp[i][j] 表示前 i 堆金币,背包容量为 j 时可以获取的最大价值。
状态转移方程为:
dp[i][j] = max(dp[i-1][j-k*m[i]] + k*v[i]),其中 0 <= k <= j/m[i]
意义为:当前考虑第 i 堆金币,可以选择不取,也可以选择取 k 个(0 <= k <= j/m[i]),取 k 个时可以获得 k*v[i] 的价值,剩余容量为 j-k*m[i],需要在前 i-1 堆金币中选择。
最终的答案为 dp[N][T]。
以下是完整的 C 语言代码实现:
```c
#include <stdio.h>
#include <string.h>
#define MAX_N 100
#define MAX_T 1000
int max(int a, int b) {
return a > b ? a : b;
}
int main() {
int N, T;
int m[MAX_N + 1], v[MAX_N + 1];
int dp[MAX_N + 1][MAX_T + 1];
memset(dp, 0, sizeof(dp));
scanf("%d %d", &N, &T);
for (int i = 1; i <= N; i++) {
scanf("%d %d", &m[i], &v[i]);
}
for (int i = 1; i <= N; i++) {
for (int j = 0; j <= T; j++) {
for (int k = 0; k <= j / m[i]; k++) {
dp[i][j] = max(dp[i][j], dp[i-1][j-k*m[i]] + k*v[i]);
}
}
}
printf("%d\n", dp[N][T]);
return 0;
}
```
阅读全文