【SeedCoder2015年热身题3 动态规划】0-1背包 (题目+答案)

【问题】

有n个重量和价值分别为wi ,vi 的物品。从这些物品中挑选出总重量不超过W的物品,求挑选方案中价值总和的最大值。

其中: wi ,vi ,W都是整数  1≤n≤100,1≤wi,vi≤100,1≤W≤10000

【输入】

每一次输入样例由三行组成,第一行有一个整数表示n的值,第二行为n对整数,分别表示第i个物品的重量和价值。第三行表示所挑选物品的最大重量。

【输出】

对于每一次输出样例,输出其最大价值。每一次样例另起一行。

【示例输入】

4

2             3             1             2             3             4             2             2

5

【示例输出】

7


【提示】

令dp[i][j]表示从前 i 个物品中选出总重量不超过 j 的物品时总价值的最大值。

则有:dp[0][j]=0;

dp[i][j] = dp[i-1][j]        (j

       或=max(dp[i-1][j],dp[i-1][j-w[i-1]]+v[i-1])   (j>=w[i-1])

最终dp[n][M]即为所求!


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

【示例代码】

//--------------------------------------【程序说明】-------------------------------------------
//		程序说明:01背包
//		程序描述:动态规划
//		IDE版本:Visual Studio 2013
//		作者:Arthur Lee
//------------------------------------------------------------------------------------------------  

//【1】头文件
#include 
#include 
#include  //包括max函数
using namespace std;

#define MAXNUMBER 100
#define MAXWEIGHT 10000
#define TIMER
//【2】函数声明
int DynamicProgram();
void InitialData();
int Search(int, int);
int MemorySearch(int, int);
//【3】定义枚举体,在几种方法中切换
enum Method
{
	DynamicProgramming,
	NormalSearch,
	SearchWithMemory
};
typedef struct tagGoods{
	int Weight;
	int Value;
}Goods;
//【4】变量声明
Goods AllGoods[MAXNUMBER];
int nCount;
int AvailableWeight;
int DP[MAXNUMBER+1][MAXWEIGHT+1];//保存中间值,DP[i][j]表示前i件商品,其重量不超过j时,所能达到的最大价值。

int main(){
#ifdef TIMER
	clock_t start = clock();
#endif // TIMER
	ifstream fin("in.txt");
	if (fin.fail())
		return 1;
	ofstream fout("out.txt");
	int nValue_temp;
	while (!fin.eof())
	{
		InitialData();
		fin >> nCount;
		for (int i = 0; i < nCount; ++i)
			fin >> AllGoods[i].Weight >> AllGoods[i].Value;
		fin >> AvailableWeight;

		Method method_temp = Method::SearchWithMemory;

		switch (method_temp)
		{
		case DynamicProgramming:
			nValue_temp = DynamicProgram();
			break;
		case NormalSearch:
			nValue_temp = Search(nCount, AvailableWeight);
			break;
		case SearchWithMemory:
			nValue_temp = MemorySearch(nCount, AvailableWeight);
			break;
		default:
			break;
		}
		fout << "the most value you can achieve is : " << nValue_temp << "\n";
	}
	
#ifdef TIMER
	clock_t end = clock();
	double duration = (double)(end - start);
	fout << "runtime : " << duration << "ms" << endl;
#endif // TIMER
	fout.close();
	return 0;
}


//【5】函数实现
int DynamicProgram(){

	for (int i = 1; i <= nCount; ++i)
		for (int j = 0; j <= AvailableWeight; ++j){
			if (AllGoods[i - 1].Weight <= j){
				DP[i][j] = max(DP[i - 1][j], (DP[i - 1][j - AllGoods[i - 1].Weight] + AllGoods[i - 1].Value));
			}
			else
				DP[i][j] = DP[i - 1][j];
		}
	return DP[nCount][AvailableWeight];
}

int Search(int i,int j){
	int result = 0;
	if (i == 0){
		return 0;
	}
	if (AllGoods[i - 2].Weight <= j)
		result = max(Search(i - 1, j), Search(i - 1, j - AllGoods[i - 2].Weight) + AllGoods[i - 2].Value);
	else
		result = Search(i - 1, j);

	return result;

}

int MemorySearch(int i, int j){
	int result = 0;

	if (DP[i][j] > 0)
		return DP[i][j];

	if (i == 0){
		return 0;
	}

	if (AllGoods[i - 2].Weight <= j)
		result = max(MemorySearch(i - 1, j), MemorySearch(i - 1, j - AllGoods[i - 2].Weight) + AllGoods[i - 2].Value);
	else
		result = MemorySearch(i - 1, j);

	DP[i][j] = result;

	return result;
}


void InitialData(){
	for (int i = 0; i < MAXNUMBER + 1; ++i)
		for (int j = 0; j < MAXWEIGHT + 1; ++j)
			DP[i][j] = 0;
}



你可能感兴趣的:(【SeedCoder2015年热身题3 动态规划】0-1背包 (题目+答案))