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

来源:互联网 发布:外国网民评论淘宝购物 编辑:程序博客网 时间:2024/05/16 00:40

【问题】

有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<w[i-1],这里w数组从0开始,因此第 i 项对应 i-1 脚标)

       或=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 <fstream>#include <ctime>#include <algorithm> //包括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 TIMERclock_t start = clock();#endif // TIMERifstream 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 TIMERclock_t end = clock();double duration = (double)(end - start);fout << "runtime : " << duration << "ms" << endl;#endif // TIMERfout.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));}elseDP[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);elseresult = 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);elseresult = 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;}



0 0
原创粉丝点击