dp--01背包--Charm Bracelet

Posted very-beginning

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了dp--01背包--Charm Bracelet相关的知识,希望对你有一定的参考价值。

Charm Bracelet

Bessie has gone to the mall‘s jewelry store and spies a charm bracelet. Of course, she‘d like to fill it with the best charms possible from the N (1 ≤ N ≤ 3,402) available charms. Each charm 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. Bessie can 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 charms with their weights and desirability rating, deduce the maximum possible sum of ratings.

Input

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

Output

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

Sample Input

4 6
1 4
2 6
3 12
2 7

Sample Output

23

首先我们要明白i,j,dp[i][j]都分别代表着什么
i:表示从1~i个物品里取
j:表示此时的最大容积
dp[i][j]:表示在1~i个物品里选取,每个物品只选择一次(限于01背包),且不超过j的容积,问所能得到的最大价值
得出一个转移方程f[i][j] = max(f[i][j], f[i - 1][j - c[i]] + w[i])
即在选取这个物品和不选这个物品中选择一个最大的
最后我们要输出的就是dp[n][m]表示在n个物品中,容积不超出m的最大价值
 1 #include <cstdio>
 2 #include <iostream>
 3 #include <algorithm>
 4 using namespace std;
 5 int dp[4000][12000];
 6 int w[1000],c[1000];
 7 int main()
 8 {
 9     int n,m;
10     scanf ("%d%d",&n,&m);
11     for (int i =1 ;i<= n;i++)
12     {
13         scanf ("%d%d",&w[i],&c[i]);
14     }
15     for (int i = 1;i <= n;i++)
16     {
17         for (int j = 0;j <= m;j++)
18         {
19             dp[i][j] = dp[i-1][j];
20             if (j-w[i]>=0)
21             {
22                 dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+c[i]);
23                 
24             }
25         
26         }    
27     //    cout<<dp[i][m]<<endl;
28     }
29     cout<<dp[n][m];
30     return 0;
31 }

 



由这一道题的数据范围,显然二维数组不可实现,我们就把二维压缩为一维
所以这时,如果我们仍正序递推,每次下一个数据都有可能用到之前我们已经更新过的数据,所以我们应该从后开始
 1 #include<iostream>
 2 using namespace std;
 3 int f[20000];
 4 int main()
 5 {
 6     int  n,v;
 7     int w[20000], c[20000];
 8     cin >> n >> v;
 9     for(int i = 1; i <= n; ++i)
10         cin >> w[i] >>c[i];
11     for(int i = 1; i <= n; ++i){
12         for (int j=v ;j>=w[i] ; j--){
13                 f[j] = max(f[j], f[j - w[i]] + c[i]);
14         }
15     }
16         cout << f[v]<<endl;
17     return 0;
18 }

 



以上是关于dp--01背包--Charm Bracelet的主要内容,如果未能解决你的问题,请参考以下文章

POJ3624 Charm Bracelet 01背包

POJ 3624 Charm Bracelet(01背包模板)

POJ 3624 Charm Bracelet(01背包裸题)

[USACO07DEC]手链Charm Bracelet——01背包

POJ - 3624 Charm Bracelet (01背包基础)

0-1背包问题,附上例题(POJ - 3624 Charm Bracelet)