DP之背包学习记录(一)

昨天看了01背包,完全背包,和多重背包这三个问题,然后呢,01和完全的区别在于顺序还是倒序.今天偷点懒,写完解题报告就滚床睡,,刚才看到了WHUD大牛的博客,好棒,真的好棒,自己要加油啦,在2015年希望有个质的飞越。

背包问题是DP问题的一个分支,所有背包问题呢,都是可以划分到01背包这个最简单基础的背包问题上,然后呢,我们要尽量类背包问题转化到01背包问题····

我们先说说01背包

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

对于这个问题呢,我们需要考虑的是放或者不放,这个才是最重要,所以不难有状态转移方程 dp[i][v] = max(dp[i-1][v],dp[i-1][v-c[i]]+w[i])

dp[i][v]表达的是第i件物品放入容积v中的价值,这个状态转移方程就两个方向,放还是不放,如果不放第i件物品的话,就应该是dp[i-1][v],也就是与i-1件物品放入容量v中的价值与放第i件商品,转化为i-1件物品放入剩下的容量为v-c[i]的背包中的价值比较。

这个复杂度已经无法优化,但是空间我们还是可以继续优化的

       for(int i = 1;i<=n;i++)物品种类
       {
           for(int j = V;j>=c[i];j--)费用
           {
               dp[j] = max(dp[j],dp[j-c[i]]+w[i]);求价值
           }
       }

恩,这个就差不多是01背包两种方法的解释了

为什么费用循环是要从V开始的呢

这正是为了保证每件物品只选一次,保证在考虑选入第i件物品这件策略时,依据的是一个绝无已经选入第i件物品的子结果f[i-1][v-c[i]]

  

基于可靠性评估序贯蒙特卡洛模拟法的配电网可靠性评估研究(Matlab代码实现)内容概要:本文围绕“基于可靠性评估序贯蒙特卡洛模拟法的配电网可靠性评估研究”,介绍了利用Matlab代码实现配电网可靠性的仿真分析方法。重点采用序贯蒙特卡洛模拟法对配电网进行长时间段的状态抽样与统计,通过模拟系统元件的故障与修复过程,评估配电网的关键可靠性指标,如系统停电频率、停电持续时间、负荷点可靠性等。该方法能够有效处理复杂网络结构与设备时序特性,提升评估精度,适用于含分布式电源、电动汽车等新型负荷接入的现代配电网。文中提供了完整的Matlab实现代码与案例分析,便于复现和扩展应用。; 适合人群:具备电力系统基础知识和Matlab编程能力的高校研究生、科研人员及电力行业技术人员,尤其适合从事配电网规划、运行与可靠性分析相关工作的人员; 使用场景及目标:①掌握序贯蒙特卡洛模拟法在电力系统可靠性评估中的基本原理与实现流程;②学习如何通过Matlab构建配电网仿真模型并进行状态转移模拟;③应用于含新能源接入的复杂配电网可靠性定量评估与优化设计; 阅读建议:建议结合文中提供的Matlab代码逐段调试运行,理解状态抽样、故障判断、修复逻辑及指标统计的具体实现方式,同时可扩展至不同网络结构或加入更多不确定性因素进行深化研究。
### 关于 AcWing 算法基础课中的 Python 实现动态规划背包问题模板 以下是基于多重背包问题的朴素版本实现的个通用 DP 背包问题代码模板。此模板适用于处理物品数量有限制的情况,即每个物品最多可以选择 `s[i]` 次。 #### 代码模板 ```python # 定义最大容量和物品数 N = 110 # 物品数量的最大值加 f = [0] * N # 初始化状态转移方程数组 def multiple_knapsack(n, m, v, w, s): """ :param n: 总共的物品数目 :param m: 背包总容量 :param v: 列表,存储第i件物品的价值 :param w: 列表,存储第i件物品的重量 :param s: 列表,存储第i件物品的数量上限 :return: 返回能够获得的最大价值 """ for i in range(1, n + 1): # 遍历每个物品 for j in range(m, 0, -1): # 倒序遍历背包剩余空间 k = 0 while k * v[i] <= j and k <= s[i]: # 添加约束条件k<=s[i] f[j] = max(f[j], f[j - k * v[i]] + k * w[i]) k += 1 return f[m] if __name__ == "__main__": n, m = map(int, input().split()) # 输入物品总数和背包容量 v, w, s = [0] * (n + 1), [0] * (n + 1), [0] * (n + 1) # 存储v,w,s for i in range(1, n + 1): v[i], w[i], s[i] = map(int, input().split()) result = multiple_knapsack(n, m, v, w, s) print(result) ``` 上述代码实现了多重背包问题的核心逻辑[^1]。通过倒序更新的方式避免重复计算,并引入了个额外变量 `k` 来控制当前物品的选择次数不超过其允许的最大值 `s[i]`。 --- #### 区间动态规划扩展说明 如果遇到更复杂的场景,比如需要记录最优解路径或者涉及区间划分的问题,则可以参考加分二叉树的做法[^3]。此时通常会增加辅助数据结构用于保存中间结果或决策过程。 例如,在某些情况下可能需要用到二维数组来表示子区间的最佳得分情况: ```python dp = [[0] * N for _ in range(N)] # dp[l][r] 表示从l到r这个范围内的最大收益 addition_info = [[None] * N for _ in range(N)] # 记录分割点或其他附加信息 ``` 这种设计模式特别适合那些不仅关注最终答案还关心具体构成细节的应用场合。 --- #### 更高效的优化方法探讨 对于大规模输入的数据集而言,朴素版的时间复杂度较高(O(n*m*sum(s)))。因此实际应用时常采用单调队列等高级技巧进步降低运行时间开销[^2]。 然而初学者建议先掌握基本形式再逐步深入学习改进策略。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值