背包问题小结--持续更新 算法基础篇(七)
2012-06-16 11:14
369 查看
View Code
// 背包问题.cpp : 定义控制台应用程序的入口点。 // //来自背包九讲 /****************************/ /* 设计者:cslave 代码说明: 背包问题 */ #include "stdafx.h" #include <iostream> using namespace std; #define NumItem 10 #define Max 100 typedef int CapType; typedef int ValueType; CapType Capacity=Max; ValueType f[NumItem][Capacity]; CapType Cost[NumItem]; ValueType Weight[NumItem]; int Amount[NumItem]; /*****************01背包问题**************************/ /* 题目:有N件物品和一个容量为V的背包。第i件物品的费用是c[i],价值是w[i]。求解将哪些物品装入背包可使价值总和最大。 状态转移方程: 用子问题定义状态:即f[i][v]表示前i件物品恰放入一个容量为v的背包可以获得的最大价值。则其状态转移方程便是: f[i][v]=max{f[i-1][v],f[i-1][v-c[i]]+w[i]} 时间和空间复杂度均为O(VN) 伪代码: procedure ZeroOnePack(cost,weight) for v=V..cost f[v]=max{f[v],f[v-cost]+weight} procedure Pack(cost[],weight[]) for i=1..N ZeroOnePack(c[i],w[i]); */ /******************分割线***************************/ void ZeroOnePack(CapType Cost,ValueType Weight) { for(CapType v=Capcity;v>=Cost;v--) f[v]=f[v]>f[v-Cost]+Weight?f[v]:f[v-Cost]+Weight; } void Pack() { for(int i=0;i<NumItem;i++) ZeroOnePack(Cost[i],Weight[i]); } /***********************完全背包问题***************************/ /* 题目:有N种物品和一个容量为V的背包,每种物品都有无限件可用。第i种物品的费用是c[i],价值是w[i]。 求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。 状态转移方程: 用子问题定义状态:即f[i][v]表示前i件物品恰放入一个容量为v的背包可以获得的最大价值。则其状态转移方程便是: f[i][v]=max{f[i-1][v-k*c[i]]+k*w[i]|0<=k*c[i]<=v} 时间复杂度O(VN) 伪代码: for i=1..N for v=0..V f[v]=max{f[v],f[v-cost]+weight} */ /************************分割线*********************************/ void CompletePack(CapType Cost,ValueType Weight) { for(CapType v=Cost;v<=Capcity;v++) f[v]=f[v]>f[v-Cost]+Weight?f[v]:f[v-Cost]+Weight; } void Pack() { for(int i=0;i<NumItem;i++) CompletePack(Cost[i],Weight[i]); } /*************************多重背包********************************/ /* 题目:有N种物品和一个容量为V的背包。第i种物品最多有n[i]件可用,每件费用是c[i],价值是w[i]。 求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。 状态转移方程: 这题目和完全背包问题很类似。基本的方程只需将完全背包问题的方程略微一改即可,因为对于第i种物品有n[i]+1种策略: 取0件,取1件……取n[i]件。令f[i][v]表示前i种物品恰放入一个容量为v的背包的最大权值,则有状态转移方程: f[i][v]=max{f[i-1][v-k*c[i]]+k*w[i]|0<=k<=n[i]} 复杂度是O(V*Σn[i])。 伪代码: procedure MultiplePack(cost,weight,amount) if cost*amount>=V CompletePack(cost,weight) return integer k=1 while k<amount ZeroOnePack(k*cost,k*weight) amount=amount-k k=k*2 ZeroOnePack(amount*cost,amount*weight) procedure Pack(cost[],weight[]) for i=1..N MultiplePack(c[i],w[i]); */ /*************************分割线***********************************/ void MultiplePack(CapType Cost,ValueType Weight,int Amount) { if (Cost*Amount>=Capacity) { CompletePack(Cost,Weight); return; } int k=1; while(k<Amount) { ZeroOnePack(k*Cost,k*Weight); Amount=Amount-k; k=k*2; } ZeroOnePack(Amount*Cost,Amount*Weight); } void Pack(CapType Cost[],ValueType weight[]) { for(int i=0;i<NumItem;i++) MultiplePack(cost[i],Weight[i],Amount[i]); }
相关文章推荐
- [Java]常见算法问题(持续学习,更新)
- 解决算法问题时需要注意的问题(持续更新中)
- Android Studio开发过程问题小结(持续更新中)
- adaboost 算法在实现中的一些问题以及解决方法(持续更新)
- 背包题目小结(持续更新中。。。长春赛H题)
- java web开发中遇到的问题及解决方案(个人学习日志,持续更新)
- 贪心算法;部分背包问题;快速排序O(nlgn);贪心算法O(n);
- 用贪心算法解决背包问题(物品可分割)
- 趣味算法-背包问题
- (基于Java)算法之动态规划——0-1背包问题
- 问题记录(持续更新)
- opencv中的内存问题(持续更新.................)
- java数据结构和算法目录(持续更新中)
- 日常遇到的常见问题记录 ------持续更新
- Storm入门(八)Storm实战常见问题总结(持续更新)
- 第七周算法作业,背包问题
- 背包问题以及DFS算法均可解之1014
- 贪心算法----背包问题
- 算法导论16.2-2--动态规划(0-1背包问题)