简单的背包问题
来源:互联网 发布:python 增量拷贝文件 编辑:程序博客网 时间:2024/06/11 21:14
背包问题(Knapsack problem)是一种组合优化的NP完全问题。问题可以描述为:给定一组物品,每种物品都有自己的重量和价格,在限定的总重量内,我们如何选择,才能使得物品的总价格最高。问题的名称来源于如何选择最合适的物品放置于给定背包中。——引用自百度百科
背包问题是熟知的不可计算问题,这里只写一下简单的“0/1背包问题”和“连续背包问题”,至于有兴趣的读者可以再去深入了解一下“完全背包问题”和“多重背包问题”
0/1背包问题:
题目:有N件物品和一个容量为V的背包。第i件物品的重量是c[i],价值是w[i]。求解将哪些物品装入背包可使这些物品的重量总和不超过背包容量,且价值总和最大。
这是最基础的背包问题,特点是:每种物品仅有一件,可以选择放或不放。如果每次可以拿走某一物品的任意一部分,则这一问题称为连续背包问题
通常0/1背包问题可以采用遵归算法来解,连续背包问题可以采用贪心算法来求解
递归算法求解0/1背包问题的示例代码:
#include<stdio.h>#include<stdlib.h>//该函数首先尝试将最后一件物品放入背包,则物品减少一件,背包可用体积相应减少,然后对当前状态进行递归……//若有解则递归结束;若无解则抛弃最后一件物品,然后对当前状态进行递归……int knap(int s, int n, int w[]) { if ( s == 0 ) return (1); else if ( s<0 || s>0 && n<1 ) return(0); else if ( knap(s - w[n-1], n - 1, w)==1 ) { //从后往前装,如果装满第n个包,剩余的重量仍然可以在剩余的n-1包中放下,那么就将第n个包装满。 printf("result: n=%d ,w[%d]=%d \n", n, n-1, w[n-1]); return (1); } else return ( knap(s, n - 1, w) );//如果装满第n个包后,剩余的重量不能在剩余的n-1包中放下,那么就不用第n个包,考虑能不能用第n-1个包。}//s:背包的重量 n:物品的数量 w[]:每件物品的重量int main() { int* w; int s = 0, n = 0, result = 0, i = 0; printf("please input s = ");/*输入s*/ scanf("%d", &s); printf("please input n = ");/*输入n*/ scanf("%d", &n); w = (int*)malloc(n*sizeof(int)); printf("please input the %d numbers(weight):\n", n);/*输入重量*/ for (i = 0; i < n; i++) scanf("%d", w+i); result = knap(s, n, w); if (result == 0) printf("no solution!\n"); return 0;}
参考资料:
1.http://zhidao.baidu.com/question/142355040.html
2.http://zhidao.baidu.com/question/189247470.html?fr=qrl&cid=866&index=1&fr2=query
3.http://www.cnblogs.com/jillzhang/archive/2007/10/06/915035.html
4.http://88myway.blog.163.com/blog/static/6926644720097124916791/
5.http://www.cppblog.com/baby-fly/archive/2009/10/24/99356.html //非递归算法
6.http://zhidao.baidu.com/question/54929204.html?fr=qrl&cid=93&index=5&fr2=query //采用链表方法
7.http://zhidao.baidu.com/question/29685294.html?fr=qrl&cid=93&index=1&fr2=query //采用栈的方法
贪心算法求解连续背包问题的示例代码:
//连续背包问题#include <iostream>#include <algorithm> #include <vector>using namespace std;#define Max 10 //初始化背包重量为10typedef struct{float price;float weight;float rate;//价格与重量的比float num;//每件物品是否能完整放下}element;bool bigger(element a,element b){return a.rate>b.rate;}void knapsack(vector<element> &test,float m){int i;for(i=0;i!=test.size();i++){if(test[i].weight>m)break;test[i].num=1;//第i件物品可以完全放到背包中m=m-test[i].weight;}if(m>0){test[i].num=m/test[i].weight;//第i件物品只能放部分i++;while(i!=test.size()){//当不是最后一件物品不能放进时test[i].num=0;i++;}}}void main(){int i,n;float m=Max;vector<element> data;element da;cout<<"input the num of goods:";cin>>n;for(i=0;i<n;i++){cout<<"input the "<<i<<" price:";cin>>da.price;cout<<"input the "<<i<<" weight:";cin>>da.weight;;da.rate=da.price/da.weight;data.push_back(da);}cout<<"build dataset:"<<endl;for(i=0;i!=data.size();i++)cout<<data[i].price<<" "<<data[i].weight<<" "<<data[i].rate<<endl;sort(data.begin(),data.end(),bigger);//将性价比最高的排在前面cout<<"after sort;"<<endl;for(i=0;i!=data.size();i++)cout<<data[i].price<<" "<<data[i].weight<<" "<<data[i].rate<<endl;cout<<"result:"<<endl;knapsack(data,m);for(i=0;i!=data.size();i++)cout<<data[i].price<<" "<<data[i].num<<endl;}
参考资料:
1.http://apps.hi.baidu.com/share/detail/16423759
2.http://wenku.baidu.com/view/ce3ebbc69ec3d5bbfd0a743e.html
3.http://wenku.baidu.com/view/afcc3e116edb6f1afe001f04.html?from=related&hasrec=1
4.http://www.cnblogs.com/gentleming/archive/2010/07/17/1779515.html
- 简单的背包问题
- 简单的背包问题
- 简单的背包问题
- 简单的背包问题
- 简单的背包问题
- 简单的背包问题
- 简单的背包问题
- 一个简单的背包问题
- 最简单的背包问题
- 简单易懂的背包问题
- 几个简单的背包问题
- 简单的背包问题--java递归实现
- 简单的0-1背包问题
- 简单的01背包问题(采药)
- 多重背包的简单问题 POJ2392
- p1054 简单背包问题的递归解法
- 0-1背包问题的简单解释
- 简单的背包最大效益问题
- hdu 1108 最小公倍数
- 人生的3个陷阱
- smarty缓存
- flex Accordion 导航器容器3 flex 教程 flex培训 flex源码 flex实例
- mac os回到桌面
- 简单的背包问题
- C计算复利增长
- article for test
- jQuery: 如何使用回调函数
- 时令变化进行养生的道理
- flex AdvancedDataGrid flex 教程 flex培训 flex源码 flex实例
- 结构体的大小、元素的对齐
- 欧几里德算法
- 找出数组中的最大值