posts - 21,comments - 0,views - 13662

01背包:在M件物品取出若干件放在空间为W的背包里,每件物品的体积为W1,W2至Wn,与之相对应的价值为P1,P2至Pn。求背包在可以装下的情况下的最大价值是多少?


  1.建立状态:令dp[M][W]为M件物品放入空间为W的背包的最大价值。

  2.分析状态转移方程:对每一个物品,仅可以选择放一个进去或者不放,所以对于第i个物品有:将前i个物品放进背包的最大价值为背包里有第i个物品与背包里没有第i个物品中两者的最大价值。

   转移方程表达为:dp[i][j]=max(dp[i-1][j],dp[i-1][j-Wi]+Pi);显然 当 i==0 或者 j==0 时:dp[i][j]=0;

  3.根据方程编程:时间复杂度( O(M*W) )

 

复制代码
const int maxn=10000;
int W,M,w[maxn],p[maxn],dp[maxn][maxn];
for(int i=1;i<=M;i++){
    for(int j=0;j<=W;j++){
        if(j>=w[i])
            dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+p[i]);
        else dp[i][j]=dp[i-1][j];
    }
}
cout<<dp[M][W];
        
复制代码

  

  4.代码优化:时间复杂度就不好优化了,但是还可以优化空间的复杂度,dp[i][j] 取决于 dp[i-1][j] 和 dp[i-1][j-w[i]] ,不依赖更前面的数据,所以可以把dp[M][W]压缩为dp[W];但是在编程的时候第二层循环就要倒着来了,因为每次求解我们需要的都是背包容量值不大于j的背包状态。这样还可以略微优化一点第二层循环的时间。时间复杂度( O(M*(W-w[i)) )

 

const int maxn=10000;
int w[maxn],p[maxn],dp[maxn];
for(int i=1;i<=M;i++)
    for(int j=W;j>=w[i];j--)
            dp[j]=max(dp[j],dp[j-w[i]]+p[i]);
cout<<dp[M][W];

 

 

  

posted on   新望  阅读(136)  评论(0)    收藏  举报
编辑推荐:
· dotnet 9 通过 AppHostRelativeDotNet 指定自定义的运行时路径
· 如何统计不同电话号码的个数?—位图法
· C#高性能开发之类型系统:从 C# 7.0 到 C# 14 的类型系统演进全景
· 从零实现富文本编辑器#3-基于Delta的线性数据结构模型
· 记一次 .NET某旅行社酒店管理系统 卡死分析
阅读排行:
· 用c#从头写一个AI agent,实现企业内部自然语言数据统计分析
· 三维装箱问题(3D Bin Packing Problem, 3D-BPP)
· Windows上,10分钟构建一个本地知识库
· 使用 AOT 编译保护 .NET 核心逻辑,同时支持第三方扩展
· Java虚拟机代码是如何一步一步变复杂且难以理解的?
< 2025年4月 >
30 31 1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 1 2 3
4 5 6 7 8 9 10

点击右上角即可分享
微信分享提示