原题链接:采药
太难理解了,特别是那个二维数组。我前几次都理解不了,好在01背包问题只要把实现部分的代码背下来也能用,我理解不了的时候就是背。
那么就用01背包问题来说,最难理解的那个二维数组很多人不知道那个i和j是什么意思
dp = [
[0, 0, 0, 0, 0, 0], 没有物品时,所有容量下的最大价值为 0
[0, 0, 0, 0, 0, 0], 只有物品 1
[0, 0, 0, 0, 0, 0], 物品 1 和 2
[0, 0, 0, 0, 0, 0] 所有物品
]
i表示第几件物品,而j表示我的背包在重量为j时,我的包里价值有多大(也就是我的包里有几件物品),这就是为什么dp数组的最后一个数就是最大值了。
而要实现“我的背包在重量为j时,我的包里价值有多大”这个问题,就用到了状态方程。
if (j < t[i]) {
dp[i][j] = dp[i - 1][j];
}
else {
dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - t[i]] + m[i]);
}
#include <stdio.h>
#define MAX 1001
#define max(a,b) (a>b?a:b)
int T, M;
int dp[MAX][MAX];
int fun(int* t, int* m) {
for (int i = 1; i <= M; i++) {
for (int j = 1; j <= T; j++) {
if (j < t[i]) {
dp[i][j] = dp[i - 1][j];
}
else {
dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - t[i]] + m[i]);
}
}
}
return dp[M][T];
}
int main() {
scanf("%d %d", &T, &M);
int t[MAX], m[MAX];
for (int i = 1; i <= M; i++) {
scanf("%d %d", &t[i], &m[i]);
}
printf("%d", fun(t, m));
}
9.9 分
1 人评分
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程
发表评论 取消回复