您的位置:首页 > 教育 > 锐评 > 网红营销_微信app开发_百度竞价点击神器奔奔_企业seo推广外包

网红营销_微信app开发_百度竞价点击神器奔奔_企业seo推广外包

2025/3/26 7:51:25 来源:https://blog.csdn.net/2301_77989601/article/details/146456924  浏览:    关键词:网红营销_微信app开发_百度竞价点击神器奔奔_企业seo推广外包
网红营销_微信app开发_百度竞价点击神器奔奔_企业seo推广外包

这段代码实现了一个完全背包问题的动态规划解法。完全背包问题与0-1背包问题类似,但每个物品可以无限次选择。以下是代码的详细思路解析:


1. 问题背景

给定 n 个物品,每个物品有其体积 v[i] 和价值 w[i],以及一个容量为 m 的背包。目标是选择物品使得总价值最大,同时总容量不超过背包的容量。与0-1背包问题不同的是,完全背包问题中每个物品可以无限次选择。

2. 动态规划的概念

动态规划是一种常用的算法技巧,用于解决具有重叠子问题和最优子结构的问题。在完全背包问题中,动态规划通过维护一个二维数组 f 来记录不同状态下的最大价值。

3. 代码逻辑解析

(1) 输入数据
cin >> n >> m;
for (int i = 1; i <= n; i++) cin >> v[i] >> w[i];
  • 用户输入物品数量 n 和背包容量 m

  • 对于每个物品,输入其体积 v[i] 和价值 w[i]

(2) 动态规划状态转移
for (int i = 1; i <= n; i++)for (int j = 0; j <= m; j++)for (int k = 0; k * v[i] <= j; k++)f[i][j] = max(f[i][j], f[i - 1][j - v[i] * k] + w[i] * k);
  1. 外层循环

    • 遍历每个物品,从第 1 个到第 n 个。

  2. 中层循环

    • 遍历背包的每个容量,从 0 到 m

  3. 内层循环

    • 遍历每个物品可以被选择的次数 k,从 0 到 j / v[i](即当前容量可以容纳的最大次数)。

  4. 状态转移

    • f[i][j] 表示前 i 个物品在容量为 j 的背包下的最大价值。

    • 不选择第 i 个物品f[i][j] = f[i - 1][j],即前 i-1 个物品在容量为 j 的背包下的最大价值。

    • 选择第 i 个物品 k:更新 f[i][j]f[i - 1][j - v[i] * k] + w[i] * k,即前 i-1 个物品在容量为 j - v[i] * k 的背包下的最大价值加上第 i 个物品的价值乘以选择次数 k

(3) 输出结果
cout << f[n][m] << endl;
  • 输出最终的最大价值,即 f[n][m]

4. 代码效率分析

  • 时间复杂度

    • 三层循环遍历所有物品、所有容量和所有选择次数,时间复杂度为 O(n × m × (m / v_min)),其中 v_min 是最小的物品体积。

  • 空间复杂度

    • 使用了一个二维数组 f,空间复杂度为 O(n × m)

5. 示例运行

输入:
3 5
1 2
2 3
3 4
运行过程:
  1. 输入数据

    • n = 3, m = 5

    • v = [1, 2, 3], w = [2, 3, 4]

  2. 动态规划状态转移

    • 初始化 f 数组为 0。

    • 对于第 1 个物品:

      • f[1][0] = 0

      • f[1][1] = 2

      • f[1][2] = 4

      • f[1][3] = 6

      • f[1][4] = 8

      • f[1][5] = 10

    • 对于第 2 个物品:

      • f[2][0] = 0

      • f[2][1] = 2

      • f[2][2] = 4

      • f[2][3] = 6

      • f[2][4] = 8

      • f[2][5] = 10

    • 对于第 3 个物品:

      • f[3][0] = 0

      • f[3][1] = 2

      • f[3][2] = 4

      • f[3][3] = 6

      • f[3][4] = 8

      • f[3][5] = 10

输出:
10

6. 总结

这段代码的核心思路是通过动态规划解决完全背包问题。通过维护一个二维数组 f,记录不同状态下的最大价值,并通过状态转移方程更新最大价值,最终找到在给定背包容量下的最大价值。这种方法的时间复杂度为 O(n × m × (m / v_min)),空间复杂度为 O(n × m),适用于中等规模的完全背包问题。

完整代码

#include<bits/stdc++.h>
using namespace std;
// 定义数组的最大长度
const int N = 1010;// n 表示物品的种类数,m 表示背包的容量
int n, m;
// v 数组存储每种物品的体积,w 数组存储每种物品的价值
int v[N], w[N];
// f 数组是二维数组,f[i][j] 表示前 i 种物品,背包容量为 j 时能获得的最大价值
int f[N][N];int main()
{// 输入物品的种类数 n 和背包的容量 mcin >> n >> m;// 循环读入每种物品的体积和价值for(int i = 1; i <= n; i ++) cin >> v[i] >> w[i];// 动态规划过程,外层循环遍历每种物品for(int i = 1; i <= n; i ++)// 中层循环遍历背包的所有可能容量for(int j = 0; j <= m; j ++)// 内层循环枚举当前物品 i 放入的数量 kfor(int k = 0; k * v[i] <= j; k ++)// 比较当前记录的最大价值 f[i][j] 和放入 k 个第 i 种物品后的价值// 放入 k 个第 i 种物品后,剩余容量为 j - v[i] * k,之前 i - 1 种物品在该剩余容量下的最大价值为 f[i - 1][j - v[i] * k]// 放入 k 个第 i 种物品的价值为 w[i] * kf[i][j] = max(f[i][j], f[i - 1][j - v[i] * k] + w[i] * k);// 输出前 n 种物品,背包容量为 m 时能获得的最大价值cout << f[n][m] << endl;return 0;
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com