0-1背包问题
2015-10-16 21:41
190 查看
#include "stdio.h" #include "stdlib.h" #define MAX 10 int n; //物品数 int c; //背包容量 int bestv = 0; //背包中所装物品的最大价值 int cw = 0; //当前已装重量 int cv = 0; //当前背包内所装物品的价值 int x[MAX]; //解向量 typedef struct Item { int w; //物品重量 int v; //物品价值 float vDw; //单位重量价值 }Item; Item item[MAX]; //物品 int cmp(const void *item1, const void *item2) //按物品单位重量价值降序 { if((*(Item *)item1).vDw < (*(Item *)item2).vDw) return 1; return 0; } //计算上界 int bound(int i) { int cv1 = cv; int cleft = c - cw; //背包剩余容量 while(i<n && item[i].w<=cleft) //当物品可装入 { cv1 += item[i].v; //当前背包所装物品价值 cleft -= item[i].w; //剩余容量减少 i++; } if(i<n) //如果没有装满 cv1 += item[i].v*cleft/item[i].w; //只装入一部分 return cv1; } //搜素到第i个物品 void backtrack(int i) { if(i>=n) //如果搜索到叶结点 { bestv = cv; return; } if(cw+item[i].w<=c) //如果当前所装重量+下一个物品重量<=背包容量,搜索左子树 { cv += item[i].v; //当前背包所装物品价值增大 cw += item[i].w; //当前背包所装物品重量增大 x[i] = 1; backtrack(i+1); //检查下一个物品 cv -= item[i].v; //返回上一层 cw -= item[i].w; } if(bound(i+1)>bestv) //如果上界>当前最优解,则可能产生最优解,搜素右子树 { x[i] = 0; backtrack(i+1); //检查下一个物品 } } void knapsack(int w[], int v[], int n1, int c1) { n = n1; c = c1; int i; int tw = 0; int tv = 0; for(i=0; i<n; i++) { item[i].w = w[i]; item[i].v = v[i]; item[i].vDw = v[i]/w[i]; tw += item[i].w; tv += item[i].v; } if(tw<=c) { printf("全部物品都被装入,总价值为:%d\n", tv); return; } qsort(item, n, sizeof(Item), cmp); //按物品单位重量价值降序 backtrack(0); } int main() { int n1 = 4; int c1 = 7; int w[] = {3, 5, 2, 1}; //物品重量数组 int v[] = {9, 10, 7 ,4}; //物品价值数组 knapsack(w, v, n1, c1); printf("背包容量为:%d\n", c); printf("物品重量分别为:"); int i; for(i=0; i<n; i++) printf("%d\t", item[i].w); printf("\n"); printf("物品价值分别为:"); for(i=0; i<n; i++) printf("%d\t", item[i].v); printf("\n"); printf("被装入的物品为:\n"); for(i=0; i<n; i++) if(x[i]) printf("物品%d(重%d,价值%d)\n", i+1, item[i].w, item[i].v); printf("\n"); printf("此时背包中所装物品的总价值为:%d\n", bestv); return 0; }
相关文章推荐
- unity3d 插件uSpeak Voice Chat 网络音频聊天
- Oracle数据库中的数据库名、全局数据库名、实例名、ORACLE_SID
- Activity--intent
- unity3d 插件 Fast Shadows 快速投影
- yii笔记—数据库1
- FastGUI教程
- 免费的ER 设计软件调研
- 二、安装SVN及配置
- Android经典底部选项卡集成方式之二
- 精品软件推荐 迅雷快鸟 中国电信宽带加速软件
- maven profile介绍
- caffe训练网络的实践
- 使用方便 正则表达式grep,sed,awk(一)
- C语言中的变量&命名规范
- csrf攻击及其防范介绍
- Android Fragment碎片使用方法汇总
- android TextView自动滚动以及Java中改变显示内容
- 【HDOJ】3277 Marriage Match III
- Android 旋转字体 实现(应用角标,如:新,火等关键字)
- iOS网络编程 - 1