算法学习-动态规划-背包问题

1 01背包

定义状态为背包容量为j时,装入前i个物品能达到的最大价值,设为dp[i][j]。
状态转移方程为:

  • j<w,dp[i][j] = dp[i-1][j] //背包装不下该物品,最大价值不变
  • j>=w, dp[i][j] = max( dp[i-1][j-w[i]] + v, dp[i-1][j] ) //和不放入该物品时同样达到该体积的最大价值比较.

代码

for(int i=1;i<=M;++i)//M是物件数量
    for(int j=1;j<=W;++j)//W为容量
    {
        if(cost[i]>j) dp[i][j]=dp[i-1][j];
        else
        {
             dp[i][j]=max(dp[i-1][j],d[i-1][j-cost[i]]+val[i]);
        }
    }
printf("%d",dp[M][T]);

滚动数组优化为一维

for(int i=1;i<=M;++i)
    for(int j=W;j>=cost[i];++j)/要反过来
    {
        dp[j]=max(dp[j],dp[j-cost[i]]+val[j]);
    }
printf("%d",dp[W]);

完全背包

定义状态为背包容量为j时,装入前i个物品(每个物品不限量)能达到的最大价值,设为dp[i][j]。
状态转移方程为

  • j<w,dp[i][j] = dp[i-1][j]剩余空间不够
  • j>=w, dp[i][j]=max( dp[i-1][j],dp[i-1][j-cost[i]]+val[i],dp[i][j-cost[i]]+val[i] ) //不放物品,放一件物品,放了一件物品继续放物品三者之间比较
    放了一件继续放肯定比放一件物品更优,所以状态转移方程可优化为
  • j<w,dp[i][j] = dp[i-1][j]剩余空间不够
  • j>=w, dp[i][j]=max( dp[i-1][j],dp[i][j-cost[i]]+val[i] ) //不放物品,放了一件物品继续放物品三者之间比较

代码

for(int i=1;i<=M;++i)//M是物件数量
    for(int j=1;j<=W;++j)//W为容量
    {
        if(cost[i]>j) dp[i][j]=dp[i-1][j];
        else
        {
             dp[i][j]=max(dp[i-1][j],d[i][j-cost[i]]+val[i]);
        }
    }
printf("%d",dp[M][T]);

滚动数组优化为一维

for(int i=1;i<=M;++i)
    for(int j=cost[i];j<=W;++j)
    {
        dp[j]=max(dp[j],dp[j-cost[i]]+val[i]);
    }
printf("%d",dp[W]);

多重背包

加上限制条件变成完全背包问题或者分组变为01背包问题,在这里我选前者。
于是,,,,研究了十几分钟。
谁说简单的啊!??有了数量限制的的话对于一个物品选或者不选会对后续选择有影响的啊??不满足无后效性。
01背包时间复杂度高出天际,二进制拆分又是啥
明天继续。

posted @ 2021-02-09 22:55  七铭的魔法师  阅读(53)  评论(0编辑  收藏  举报