zoukankan      html  css  js  c++  java
  • 动态规划—背包问题(01背包、完全背包、多重背包)

    01背包问题

    N件物品和一个容量为C的背包。第i件物品的费用是w[i],价值是v[i]。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。

     

    w[i] 表示物品i的重量

    v[i] 表示物品i的价值

    C 表示背包的容量

    dp[i][c]表示前i件物品恰放入一个容量为c的背包可以获得的最大价值

     

    状态转移方程:

    二维: dp[i][c] = max(dp[i-1][c],dp[i-1][c-w[i]]+v[i])

    一维: dp[c] = max(dp[c],dp[c-w[i]]+v[i])  //max里的dp[c]dp[c-w[i]]保存的是状态dp[i-1][c]和状态dp[i-1][c-w[i]]的值

     

    01背包 降维代码:

    memset(dp,0,sizeof(dp));   //init

    for(int i=1; i<=n; i++)

            for(int c=C; c>=w[i]; c--)  //注意,c要由C倒推到w[i],c<w[i],dp[c] = dp[c]; 所以不用写了...

                   dp[c] = max(dp[c],dp[c-w[i]]+v[i]);     //c要倒推才能保证在推dp[c],max里的dp[c]dp[c-w[i]]保存的是状态dp[i-1][c]和状态dp[i-1][c-w[i]]的值

     

     

    完全背包问题

    N种物品和一个容量为C的背包,每种物品都有无限件可用。第i种物品的费用是w[i],价值是v[i]。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大

     

    状态转移方程:

    二维: dp[i][c] = max(dp[i-1][c],dp[i][c-w[i]]+v[i])

    一维: dp[c] = max(dp[c],dp[c-w[i]]+v[i])  //max里的dp[c]dp[c-w[i]]保存的是状态dp[i-1][c]和状态dp[i][c-w[i]]的值

     

    完全背包 降维代码:

    memset(dp,0,sizeof(dp));   //init

    for(int i=1; i<=n; i++)

            for(int c=w[i]; c<=C; c--)   //注意,c要正推

                   dp[c] = max(dp[c],dp[c-w[i]]+v[i]);     //c要正推才能保证在推dp[c],max里的dp[c]dp[c-w[i]]保存的是状态dp[i-1][c]和状态dp[i][c-w[i]]的值

     

    多重背包问题

    N种物品和一个容量为C的背包,每种物品的数量有限,i种物品的费用是w[i],价值是v[i],数量为n[i]

    可将该问题转化为01背包和完全背包问题:

    如果w[i]*n[i] > C, 按照完全背包问题进行求解;

    如果w[i]*n[i] < C, 按照01背包问题进行求解。

  • 相关阅读:
    分层图最短路(DP思想) BZOJ2662 [BeiJing wc2012]冻结
    动态规划 BZOJ1925 地精部落
    线性DP SPOJ Mobile Service
    线性DP codevs2185 最长公共上升子序列
    数位DP POJ3208 Apocalypse Someday
    线性DP POJ3666 Making the Grade
    杨氏矩阵 线性DP? POJ2279 Mr.Young's Picture Permutations
    tarjan强连通分量 洛谷P1262 间谍网络
    树链剖分 BZOJ3589 动态树
    二分图 BZOJ4554 [Tjoi2016&Heoi2016]游戏
  • 原文地址:https://www.cnblogs.com/jmliao/p/9241091.html
Copyright © 2011-2022 走看看