动态规划_0-1背包问题

     0-1背包问题是一个经典的问题,可以用动态规划以线性的时间解决,相比于蛮力求解,动态规划的各项性能都比较好。关于0-1背包问题的具体解释请见下面这篇博客:

      http://www.cnblogs.com/Christal-R/p/Dynamic_programming.html

    这篇博客对0-1背包问题的分析很透彻,也提出了自己的改进算法,我就不做具体论述,我借鉴其中的思想,写下一下代码

#include<iostream>
#include<cmath>
#include<algorithm>
#include<utility>    //为返回两个一维数组,使用pair
using namespace std;

int number;  //商品个数
int capacity;  //背包容量

int* item = new int[number + 1];


pair<int*, int*> Create()
{
	
	int* w = new int[number + 1];
	int* v = new int[number + 1];

	for (int i = 1; i <= number; i++)
	{
		w[i] = i + 1;
		v[i] = i + 2;
	}
	pair<int*, int*> result(w, v);
	return  result;
}




int** Knapsack_Problem( pair<int*, int*> result)
{	
	int** V = new int*[number + 1];
	for (int z = 0; z <= number; z++)
		V[z] = new int[capacity + 1];

	for (int x = 0; x <= number; x++)
		V[x][0] = 0;

	for (int y = 0; y <= capacity; y++)
		V[0][y] = 0;


	int i, j;
	for(int i = 1;i<=number; i++)
	{
		for (j = 1; j <= capacity; j++)
		{
			if (j < result.first[i])  //装不下
			{
				V[i][j] = V[i - 1][j];
			}
			else  //装的下
			{
				V[i][j] = max(V[i - 1][j],V[i - 1][j - result.first[i]] + result.second[i]);
			}
		}
	}

	return V;
}


void FindWhat(int i,int j,int** V,int* item, pair<int*, int*> result)
{
	if (i > 0 && j>0)
	{
		if (V[i][j] == V[i - 1][j])//相等说明没装
	        {
	            item[i] = 0;//全局变量,标记未被选中
	            FindWhat(i - 1, j,V, item, result);
	        }
       else if (j - result.first[i] >= 0 && V[i][j] == V[i - 1][j - result.first[i]] + result.second[i])
	        {
	            item[i] = 1;//标记已被选中
	           FindWhat(i - 1,j- result.first[i], V, item, result);//回到装包之前的位置
	        }
	}
}

void printf(int* item)
{
	for (int i = 0; i <= number; i++)
	{
		if (item[i] == 1)
		{
			cout << i << "号" << "\t";
		}
	}
	cout << endl;
}

int main()
{
	cout << "plase enter the number of goods: " << endl;
	cin >> number;
	cout << "plase enter the capacity of knapsack: " << endl;
	cin >> capacity;

	pair<int*, int*> result = Create();
	int** V = Knapsack_Problem(result);

	for (int i = 0; i <= number; i++)
	{
		for (int j = 0; j <= capacity; j++)
		{
			cout << V[i][j] << "\t";
		}
		cout << endl;
	}

	
	for (int i = 0; i <= number; i++)
	{
		item[i] = 0;
	}

	FindWhat(number, capacity, V, item, result);
	cout << "最大价值为" << V[number][capacity] << endl;
	cout << "商品号码为" << endl;
	printf(item);

	return 0;
}

  动态规划算法在很多问题上都有很好的应用,理解其中的原来至关重要

       夜深了,你在哪里

posted on 2017-09-15 19:52  wu_xin  阅读(177)  评论(0编辑  收藏  举报

导航