• 背包问题温习


    01背包:选一次,即 用一维优化时,需要倒序,因为选取的是上一行的更新,如果正序操作会覆盖掉最小的体积

    完全背包:一个物品可以选多次,即 一维用优化时,正序即可,因为我们物品可以选多次,上一个转移方程可以来自同一行的前面几个值

    若用二维,01背包是上一个背包转移过来的所以 i  - 1

    完全背包二维的话就是直接 i 

    1. //完全背包(与01背包不同,物品可以放多次)
    2. #include
    3. #include
    4. using namespace std;
    5. const int N = 10010;
    6. int f[N][N];
    7. int v[N],w[N];
    8. int n,m;
    9. int main()
    10. {
    11. cin>>n>>m;
    12. for(int i = 1;i <= n;i++)
    13. {
    14. cin>>v[i]>>w[i];
    15. }
    16. for(int i = 1;i <= n;i++)
    17. {
    18. for(int j = 1;j <= m;j++)
    19. {
    20. if(j < v[i])f[i][j] = f[i-1][j];
    21. else f[i][j] = max(f[i-1][j],f[i][j-v[i]] + w[i]);
    22. }
    23. }
    24. cout<
    25. return 0;
    26. }
    27. //一维优化
    28. #include
    29. #include
    30. using namespace std;
    31. const int N = 10010;
    32. int f[N];
    33. int v[N],w[N];
    34. int n,m;
    35. int main()
    36. {
    37. cin>>n>>m;
    38. for(int i = 1;i <= n;i++)
    39. {
    40. cin>>v[i]>>w[i];
    41. }
    42. for(int i = 1;i <= n;i++)
    43. {
    44. for(int j = 1;j <= m;j++)
    45. {
    46. if(j < v[i]) f[j] = f[j];
    47. else f[j] = max(f[j],f[j-v[i]] + w[i]);
    48. }
    49. }
    50. cout<
    51. return 0;
    52. }
    53. //继续优化
    54. #include
    55. #include
    56. using namespace std;
    57. const int N = 10010;
    58. int f[N];
    59. int v[N],w[N];
    60. int n,m;
    61. int main()
    62. {
    63. cin>>n>>m;
    64. for(int i = 1;i <= n;i++)
    65. {
    66. cin>>v[i]>>w[i];
    67. }
    68. for(int i = 1;i <= n;i++)
    69. {
    70. for(int j = v[i];j <= m;j++)
    71. {
    72. f[j] = max(f[j],f[j-v[i]] + w[i]);
    73. }
    74. }
    75. cout<
    76. return 0;
    77. }

    多重背包一

    其实就是01背包的变种,不过我们需要用二进制优化

    1. //多重背包(有范围限定)
    2. //可以转化成01背包完成
    3. #include
    4. #include
    5. using namespace std;
    6. const int N = 10010;
    7. int n,m;
    8. int f[N][N],v[N],w[N],ans;
    9. int s[N];
    10. int main()
    11. {
    12. cin>>n>>m;
    13. for(int i = 1;i <= n;i++)
    14. {
    15. cin>>v[i]>>w[i];
    16. }
    17. for(int i = 1;i <= n;i++)
    18. {
    19. for(int j = m;j >= v[i];j--)
    20. {
    21. for(int k = 0;k <= s[i] && k * v[i] <= j;k++)
    22. f[j] = max(f[j],f[j - k * v[i]] + k * w[i]);
    23. }
    24. }
    25. //复杂度太高,不适合写
    26. return 0;
    27. }
    28. //二进制优化
    29. //(优化为01背包问题)
    30. #include
    31. #include
    32. using namespace std;
    33. const int N = 10010;
    34. int n,m,v,w,s;
    35. int vv[N],ww[N];
    36. int f[N];
    37. int main()
    38. {
    39. cin>>n>>m;
    40. int num = 1;
    41. for(int i = 1;i <= n;i++)
    42. {
    43. cin>>v>>w>>s;
    44. for(int j = 1;j <= s;j<<=1)
    45. {
    46. vv[num] = j * v;//存体积
    47. ww[num++] = j * w;//存价值
    48. s -= j;//减去拆分系数
    49. }
    50. if(s)//剩余
    51. {
    52. vv[num] = s * v;
    53. ww[num++] = s * w;
    54. }
    55. }
    56. for(int i = 1;i < num;i++)//小于num是因为退出num拆分循环的时候,num++
    57. {
    58. for(int j = m;j >= vv[i];j--)
    59. {
    60. f[j] = max(f[j],f[j - vv[i]] + ww[i]);
    61. }
    62. }
    63. cout<
    64. return 0;
    65. }

     

  • 相关阅读:
    Powdersigner + PostgreSql 同步表结构到pg数据库
    element ui el-table表格复选框,弹框关闭取消打勾选择
    面经综合总结
    【堆】数据结构-堆的实现【超详细的数据结构教学】
    澳大利亚博士后招聘|皇家墨尔本理工学院材料科学
    学习ASP.NET Core Blazor编程系列五——列表页面
    如何实现施耐德Twido系列PLC远程上下载
    【leetcode】【周赛】第 307 场
    Python中的del用法
    修改ONNX模型节点
  • 原文地址:https://blog.csdn.net/Demilly123/article/details/127941312