背包问题(Knapsack problem)之01

来源:互联网 发布:淘宝我的积分查询 编辑:程序博客网 时间:2024/05/18 02:58

问题描述:

给定一组物品,每种物品都有自己的重量和价格,在限定的总重量内,我们如何选择,才能使得物品的总价格最高。


转移方程:dp[i][j] = max(dp[i-1][j],dp[i-1][j-weight[i]] + value[i])

                                          不放                       放入

其中dp[i][j]表示放入i个物品,总价值为j。

代码如下:

// beibaoproblem.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include <iostream>using namespace std;#define max(a, b) ( (a) > (b) ? (a) :(b) )int _tmain(int argc, _TCHAR* argv[]){const int v = 10;  //最大容量const int n = 3;  //物件的个数int value[] = {4,5,6};int weight[] = {3,4,5};int temp1, temp2;int i,j;int dp[n + 1][v + 1];//初始化for (i = 0; i < n+1; i++)for (j = 0; j < v + 1; j++){dp[i][j] = 0;}for(i = 1; i <= n; i++){for (j = 1; j <= v; j++){if (j >= weight[i-1])//表示剩余容量大于第i件的容量,可以放入{dp[i][j] = max(dp[i-1][j], dp[i-1][j - weight[i-1]] + value[i-1]);}else              //反之不放入{dp[i][j] =  dp[i-1][j]; }}}for (i = 0; i < n+1; i++){for (j = 0; j < v + 1; j++){cout << dp[i][j]<<" " ;}cout << endl;}cout <<  dp[n][v];return 0;}

结果:



-----------------------------------------------------------------------------------------------------

以下是从文件读取:

// beibaoproblem.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include <iostream>using namespace std;#define FILENAMELENGTH 1000#define max(a,b) (a) > (b) ? a : bclass CBeibao{public:int m_nNumber;     //物品数量int m_nMaxWeight;  //最大载重量int *m_pWeight;  //每个物品的重量int *m_pValue;   //每个物品的价值int *m_pCount;   //每个物品被选中的次数int m_nMaxValue; //最大价值public:CBeibao(const char* filename);~CBeibao();int GetMaxValue();//n表示物品个数,m背包载重量,w数组重量,v价值数组,c是否被选中数组int GetMaxValue(int n, int m, int *w, int *v, int *c); void Display(int nmaxValue);void Display(int nMaxValue, const char* filename);};//读入数据CBeibao::CBeibao(const char* filename){FILE *fp;fopen_s(&fp, filename, "r");if (fp == NULL){printf_s("can not open file");return;}fscanf_s(fp, "%d%d", &m_nNumber, &m_nMaxWeight);m_pWeight = new int[m_nNumber+1];m_pValue = new int[m_nNumber+1];//读入每个物品的重量m_pWeight[0] = 0;for(int i = 1; i <= m_nNumber; i++)fscanf_s(fp, "%d", m_pWeight+i);//读入每个物品的价值m_pValue[0] = 0;for(int i = 1; i <=m_nNumber;i++)fscanf_s(fp, "%d", m_pValue+i);//初始化每个物品被选中次数为0m_pCount = new int[m_nNumber+1];for(int i = 0; i <=m_nNumber;i++)m_pCount[i] = 0;fclose(fp);}CBeibao::~CBeibao(){delete[] m_pWeight;m_pWeight = NULL;delete[] m_pValue;m_pValue = NULL;delete[] m_pCount;m_pCount = NULL;}int CBeibao::GetMaxValue(int n, int m, int *w, int *v, int *c)//n表示物品个数,m背包载重量,w数组重量,v价值数组,c是否被选中数组{int row = n+1;int col = m+1;int i,j;//value[i][j]表示前i个物品能装入载重量为j的背包中物品的最大价值int **value = new int *[row];for(i = 0; i < row; i++)value[i] = new int[col];//初始化为0for(i = 0; i < row; i++)for(j = 0; j < col; j++) value[i][j] = 0;//计算for(i = 1; i < row; i++)for (j = 1; j < col; j++){if (j >= w[i]){value[i][j] = max(value[i-1][j], value[i-1][j - w[i]] + v[i]);}else{value[i][j] = value[i-1][j];}}//逆推求装入的物品j = m;for (i = row - 1; i > 0; i--){if (value[i][j] > value[i-1][j])  //表示第i个物品装入{c[i] = 1;j -= w[i];}}//记录最大价值int nMaxValue = value[row-1][col-1];//释放该二维数组for (i = 0; i < row; i++){delete[col] value[i];value[i] = NULL;}delete[] value;value = NULL;return nMaxValue;}int CBeibao::GetMaxValue(){int nValue = GetMaxValue(m_nNumber, m_nMaxWeight, m_pWeight, m_pValue, m_pCount);m_nMaxValue = nValue;return nValue;}//显示结果void CBeibao::Display(int nMaxValue){_tprintf(_T(" %d"), nMaxValue);for(int i = 1; i <= m_nNumber; i++){if (m_pCount[i])  _tprintf(_T(" %d %d"), i, m_pCount[i]);}_tprintf(_T(""));}void CBeibao::Display(int nMaxValue, const char* filename){FILE *fp;fopen_s(&fp, filename, "w");if (fp == NULL){_tprintf(_T("can not write file!"));return;}fprintf(fp, "%d", nMaxValue);for (int i = 1; i <= m_nNumber; i++){if (m_pCount[i]){fprintf(fp, "%d %d", i, m_pCount[i]);}}fclose(fp);}int _tmain(int argc, _TCHAR* argv[]){char sinput[10];char sfilename[FILENAMELENGTH] = "C:\\Users\\sony\\Desktop\\k\\practice\\beibaoproblem\\beibaoproblem\\input.txt";scanf_s("%s", sinput, _countof(sinput));while (_stricmp(sinput, "q") != 0){if (_stricmp(sinput, "i") == 0){_tprintf(_T(" please input a filename:"));/*scanf_s("%s", sfilename);*///获取满足最大载重量的最大价值CBeibao beibao(sfilename);int nMaxValue = beibao.GetMaxValue();if (nMaxValue){beibao.Display(nMaxValue);int nlen = strlen(sfilename);//这里sfilename表示头指针,sttrcpy表示复制到sfilename + nlen - 4strcpy_s(sfilename + nlen - 4, FILENAMELENGTH , "_result.txt");beibao.Display(nMaxValue, sfilename);}else{_tprintf(_T("error!"));}}_tprintf(_T("input command: "));scanf_s("%s", sinput);}return 0;}

参考链接:http://blog.csdn.net/livelylittlefish/article/details/2186206

                    http://www.cnblogs.com/usa007lhy/archive/2013/05/19/3087195.html

0 0
原创粉丝点击