问题说明:
假设有一个背包的负重最多可达8公斤,而希望在背包中装入负重范围内可得之总价物
品,假设是水果好了,水果的编号、单价与重量如下所示:
0
李子
4KG
NT$4500
1
苹果
5KG
NT$5700
2
橘子
2KG
NT$2250
3
草莓
1KG
NT$1100
解法背包问题是关于最佳化的问题,要解最佳化问题可以使用「动态规划」 (Dynamicprogramming) ,从空集合开始,每增加一个元素就先求出该阶段的最佳解,直到所有的元素加入至集合中,最后得到的就是最佳解。
下面我们看下代码:
/* 问题: 假设有一个背包的负重最多可达8公斤,而希望在背包中装入负重范围内可得之总价物品 算法说明: 采用动态规划,在当前阶段求解出最好的解,如此反复 日期:2013/8/18 张威 */ #include <iostream> #include <time.h> using namespace std; #define MAXSIZE 8 //定义全局变量 char name[5][5] = {"李子","苹果","橘子","草莓","甜瓜"};//水果名称 int wight[5] = {4,5,2,1,6};//单个水果所占斤数 int price[5] = {4500,5700,2250,1100,6700};//单个水果的价值 int perkg_price[5];//每斤水果的价钱 int perkg_num[5] = {0,1,2,3,4}; void GetNmae(int num) { for (int i = 0;i <= 4;i++) { cout<<name[num][i]; } } void GetBestAnswer(int currentwigh) { //判断递归终止条件 if (currentwigh >= MAXSIZE) { cout<<"包裹已经满了,无法再装进东西"<<endl; } else { //check用来表证到底剩下来的物品里面还有没有能装进去背包里的 bool check = true; int i = 0; for (;i <= 4;i++) { //若是没有进入到这个条件内,说明剩下来的物品的重量都超过了背包剩余重量,到此结束.否则i就代表当前所能选中的最优解 if (wight[perkg_num[i]] <= MAXSIZE-currentwigh) { check = false; break; } } if (check == true) { cout<<"已经装不进去任何水果了"<<endl; } else { //得到最优解,并且将当前重量增加,进入下一次递归 currentwigh += wight[perkg_num[i]]; cout<<"购买了"; GetNmae(perkg_num[i]); cout<<endl; GetBestAnswer(currentwigh); } } } int main() { //计算出每斤水果的价钱,便于动态规划时求出当前最佳解 for (int i = 0;i <= 4;i++) { perkg_price[i] = price[i] / wight[i]; } //对perkg_num进行排序,同时保证单价和perkg_num之间的一一对应关系.即两个数组要同时变化 //采用的是冒泡排序,在元素进行交换时perkg_num和perkg_price同时变化 for (int i = 0;i <= 3;i++) { for (int j = i;j <= 3;j++) { if (perkg_price[j] < perkg_price[j+1]) { int temp1 = perkg_price[j]; int temp2 = perkg_num[j]; perkg_price[j] = perkg_price[j+1]; perkg_price[j+1] = temp1; perkg_num[j] = perkg_num[j+1]; perkg_num[j+1] = temp2; } } } //开始计算求解 GetBestAnswer(0); return 0; }