POJ 3624:CharmBracelet (0-1背包问题)

原创 2018年04月15日 11:20:10

题目来源:http://poj.org/problem?id=3624

3624CharmBracelet

总时间限制: 1000ms      内存限制: 65536kB

Description

Bessie has gone to the mall's jewelry store and spies a charmbracelet. Of course, she'd like to fill it with the best charms possible fromthe N (1 ≤ N ≤ 3,402) available charms. Eachcharm i in the supplied list has a weight Wi (1≤ Wi ≤ 400), a 'desirability' factor Di (1≤ Di ≤ 100), and can be used at most once. Bessiecan only support a charm bracelet whose weight is no more than M (1≤ M ≤ 12,880).

Given that weight limit as a constraint and a list of the charmswith their weights and desirability rating, deduce the maximum possible sum ofratings.

Input

* Line 1: Two space-separated integers: N and M
* Lines 2..N+1: Line i+1 describes charm i withtwo space-separated integers: Wi and Di

Output

* Line 1: A single integer that is the greatest sum of charmdesirabilities that can be achieved given the weight constraints

Sample Input

4 6

1 4

2 6

3 12

2 7

SampleOutput

23

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

解题思路

0-1背包问题:动态规划

递推表达式:

DP[n][m]表示有n件物品,背包容量W为m时的最大化收益R

DP[n][m] = max(DP[n-1][m-w[n]] + r[n]), DP[n-1][m])

max里的第一项表示放入第n件物品,m表示不放入

由于每次递推只用到第n-1行和第n行,所以只需用一个数组存储一行

这是递推表达式变为:

DP[m] = max ( DP[m-w[n]]+ r[n], DP[m])

由于第n行的结果对第n-1行是覆盖写入,故循环时要从大往小了循环,否则会造成用第n行的结果更新第n行的结果,物理意义是将一个物品放入背包多次。

核心代码

memset(dp, 0, (m+1)*sizeof(int));				// 初始化
for (i=0; i<n; i++)								// 对于每一件物品
{
	for (j=m; j>=w[i]; j--)						// 倒着算保证每件物品只被放一次
	{
		dp[j] = max(dp[j-w[i]] + d[i], dp[j]);	// 降维的递推表达式
	}
}
cout << dp[m];

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

代码

#include<fstream>
#include<iostream>
#include<cstring>
using namespace std;

int main()
{
#ifndef ONLINE_JUDGE
	ifstream fin("poj3624.txt");
	int n,m,i,j;
	fin >> n >> m;
	int* w = new int[n];
	int* d = new int[n];
	for (i=0; i<n; i++)
	{
		fin >> w[i] >> d[i];
	}
	fin.close();
	int *dp = new int[m+1];							// 动态规划一维数组
	// 递推式:dp[n][w] = max( dp[n-1][w-w[n]] + d[n], dp[n-1][w] )
	memset(dp, 0, (m+1)*sizeof(int));				// 初始化
	for (i=0; i<n; i++)								// 对于每一件物品
	{
		for (j=m; j>=w[i]; j--)						// 倒着算保证每件物品只被放一次
		{
			dp[j] = max(dp[j-w[i]] + d[i], dp[j]);	// 降维的递推表达式
		}
	}
	cout << dp[m];

	delete[] w;
	delete[] d;
	delete[] dp;
	return 0;
#endif
#ifdef ONLINE_JUDGE
	int n,m,i,j;
	cin >> n >> m;
	int* w = new int[n];
	int* d = new int[n];
	for (i=0; i<n; i++)
	{
		cin >> w[i] >> d[i];
	}
	int *dp = new int[m+1];							// 动态规划一维数组
	// 递推式:dp[n][w] = max( dp[n-1][w-w[n]] + d[n], dp[n-1][w] )
	memset(dp, 0, (m+1)*sizeof(int));				// 初始化
	for (i=0; i<n; i++)								// 对于每一件物品
	{
		for (j=m; j>=w[i]; j--)						// 倒着算保证每件物品只被放一次
		{
			dp[j] = max(dp[j-w[i]] + d[i], dp[j]);	// 降维的递推表达式
		}
	}
	cout << dp[m];

	delete[] w;
	delete[] d;
	delete[] dp;
	return 0;
#endif
}


poj3624 0-1背包问题

#include #include using namespace std; static const int N = 3403; static const int M = 12881; stat...
  • ych_ding
  • ych_ding
  • 2013-09-23 13:16:41
  • 1598

POJ 3624 0-1背包问题

#include #define max(a,b) ((a) > (b) ? (a) : (b))int sum[12881],c,w,N,M;int main(){ int i,j,maximum ...
  • jollyjumper
  • jollyjumper
  • 2010-02-09 00:14:00
  • 421

POJ 3624 0-1背包问题 动态规划

    第一道背包问题,0-1背包,参考网上一位大牛写的做的。状态方程:dp[i][w] = max{dp[i-1][w], dp[i-1][w-obj[i].wei] + obj[i].val]},...
  • yangliuy
  • yangliuy
  • 2010-11-30 23:57:00
  • 2085

poj3624 dp 01背包

链接:点我 很简单的01。。。 #include #include using namespace std; #define max(a,b) ((a)>(b)?(a):(b)) cons...
  • liuqiyao_01
  • liuqiyao_01
  • 2013-04-01 13:02:52
  • 2431

算法设计0-1背包问题

  • 2010年04月10日 21:53
  • 542B
  • 下载

POJ 3624

这是个典型的01背包问题,很基础的,我就做了。 题目大意: 在N个花费为Ci、价值为Wi的物品中(i=1...N),选取若干个,使得所有物品的总花费不大于M,而其总价值最大。 -----------...
  • hello_cosmos
  • hello_cosmos
  • 2013-11-22 16:16:02
  • 710

poj_3624 01背包

01背包的DP状态转移方程: 考虑第i件物品; 如果背包装的下第i件物品,则state[i][j] = max {state[i-1][j] , state[i-1][j-w[i]+v[i]}; 如果...
  • yeruby
  • yeruby
  • 2015-03-02 16:08:48
  • 469

通俗理解0-1背包问题解法

0-1背包问题是一个很经典的问题,使用动态规划算法来求解也是很经典的。下面我用一个例子来讲解用动态规划算法求解0-1背包问题。 假设商店中有5件东西,重量用w表示,价格用v表示 ...
  • liu_c_y
  • liu_c_y
  • 2016-11-19 23:19:35
  • 416

0-1背包问题分析及代码实现

0-1背包问题 动态数组申请
  • chen372901
  • chen372901
  • 2016-08-30 21:39:20
  • 802

动态规划—0-1背包问题(最易理解的讲解)

0-1背包问题是最广为人知的动态规划问题之一,拥有很多变形。尽管在理解之后并不难写出程序,但初学者往往需要较多的时间才能掌握它。小编写这篇文章力争做到用通俗易懂的语言,最少的公式把0-1背包问题讲解透...
  • u010293698
  • u010293698
  • 2015-10-08 22:50:34
  • 3399
收藏助手
不良信息举报
您举报文章:POJ 3624:CharmBracelet (0-1背包问题)
举报原因:
原因补充:

(最多只允许输入30个字)