• 29. 一道简单背包题


    目录

    题目

    思路

    注意事项

     C++完整代码


    题目

    Description
    龙神有很多背包,每一个背包都有一个容积。但是这些背包的容积都恰好是一个数字的整数倍,比如,,等等。并且对于任意,容积为的背包都存在。
    龙神有一些物品要装进背包,第个物品占据的体积。现在,龙神想选出一些物品,使得存在一个背包可以恰好放下这些物品,并且这个背包放满。
    龙神想知道这样的取法有多少个,请你帮他算一算吧?由于取法很多,你只需要输出取法的末七位数,没有前导零,即可(即对10000000取模)。
    Input
    第一行两个数,分别表示物品数和背包体积的基数。
    第二行个数,分别表示每个物品的体积。
    Output
    输出一行一个数,表示取法总数的末七位。

    测试输入期待的输出时间限制内存限制额外进程
    测试用例 1以文本方式显示
    1. 4 5↵
    2. 1 2 3 2↵
    以文本方式显示
    1. 3↵
    1秒64M0


    思路

    1.确定dp数组及其下标的含义

    dp数组用于记录背包容量为j时的取法总数,其下标表示背包容量。

    数组dp的长度为2*V+1,其中V是背包体积的基数。

    2.确定递推公式

    对于每个物品i,背包容量j,存在递推公式dp[j] = dp[j] + dp[j - p[i]]。其中,dp[j]代表当前背包容量j下的取法总数,dp[j-p[i]]表示加上当前物品体积后的背包容量(即j-p[i])下的取法总数。

    3.dp数组初始化

    首先将dp数组所有元素都初始化为0。然后初始化dp[0] = 1,表示背包容量为0时有一种取法。

    4.遍历顺序

    使用两个嵌套的for循环进行遍历。

    外层循环遍历每个物品,内层循环从背包容量的最大值2V递减到物品体积p[i]。

    这种遍历顺序确保在计算dp[j]时,可以利用上一轮计算的dp[j-p[i]]的值。另外,为了保证在更新dp[j]时,不影响后续计算,第二个内层循环是从2V递减到p[i]的,这样可以避免重复更新dp[j-p[i]]


    注意事项

    1. 题目要求输出取法总数的末七位数,即对结果取模10000000。在代码中,对dp数组元素进行累加操作时,要注意取模运算,以防止数值溢出。

    2. 题目给出了背包容量的基数V,即背包容量都是V的整数倍。在读取每个物品的体积后,需要对其进行取模运算,以保证它们都能装进背包,如果取模结果为0,则将其置为V。

    3. 使用long long存储数据


     

     C++完整代码

    1. #include
    2. #include
    3. using namespace std;
    4. int main() {
    5. int n, V;
    6. cin >> n >> V;
    7. // 创建一个长度为n+1的数组p来存储每个物品的体积
    8. vector<long long> p(n + 1);
    9. for (int i = 1; i <= n; i++) {
    10. cin >> p[i];
    11. p[i] %= V;
    12. if (p[i] == 0)
    13. p[i] = V;
    14. }
    15. // 初始化dp数组,长度为2*V+1,用来记录背包容积为i时的取法总数
    16. vector<long long> dp(2 * V + 1, 0);
    17. dp[0] = 1;
    18. // 动态规划求解
    19. for (int i = 1; i <= n; i++) {
    20. for (int j = 2 * V; j >= p[i]; j--) {
    21. // 更新dp[j]为原来的值加上dp[j-p[i]]
    22. dp[j] = (dp[j] + dp[j - p[i]]) % 10000000;
    23. }
    24. for (int j = 2 * V; j >= p[i]; j--) {
    25. if (j > V) {
    26. // 如果背包容积j大于V,则将dp[j-V]加上dp[j],并将dp[j]置为0
    27. dp[j - V] = (dp[j - V] + dp[j]) % 10000000;
    28. dp[j] = 0;
    29. }
    30. }
    31. }
    32. // 输出答案,即背包容积为V时的取法总数的末七位数
    33. cout << dp[V] % 10000000 << endl;
    34. return 0;
    35. }

  • 相关阅读:
    【Linux守护进程】二、守护进程详解
    postman在ubuntu下报gpu-disable
    Linux的基本操作
    【前端面试知识题】- 6.1 Vue.js
    Qt 自定义主题颜色,颜色选择器
    ManualResetEvent
    【教程8】疯壳·ARM功能手机-GPIO实验教程
    垃圾分类解决方案-最新全套文件
    Perforce发布《2023游戏开发与设计现状报告》,为游戏开发行业提供参考
    【Vue】VUE模板vue-admin-template-4.4.0添加角色权限路由
  • 原文地址:https://blog.csdn.net/m0_74200772/article/details/132730355