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 iin 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.
输入
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
输出
Line 1: A single integer that is the greatest sum of charm desirabilities that can be achieved given the weight constraints
输入样例
4 6
1 4
2 6
3 12
2 7
输出样例
23
实现代码
#include <iostream>
#include <algorithm>
using namespace std;
const int max_n=3405;
const int max_m=12900;
int weight[max_n];
int desir[max_n];
int f[max_m]={0};
int N,M;
int main(){
cin>>N>>M;
for(int i=1;i<=N;i++){
cin>>weight[i]>>desir[i];
}
for(int i=0;i<weight[1];i++){
f[i]=0;
}
for(int i=weight[1];i<=M;i++){
f[i]=desir[1];
}
for(int i=2;i<=N;i++){
for(int j=M;j>=0;j--){
if(j>=weight[i]){
f[j]=max(f[j],f[j-weight[i]]+desir[i]);
}
}
}
cout<<f[M];
return 0;
}
解题思想
用 f [ i ] [ j ]表示取前 i 种魅力符,使它们总质量不超过 j 的最优取法取得的魅力值总和。
边界条件
当只有一个魅力符的时候,选择取与不取,即N=1。这时候如果这个物品的重量weight[1]<=M,说明可以取:f[0][M]=desir[1]。否则,weight[1]>M,说明镯子容不下这颗:f[0][M]=0。
递推
f [ i ][ j ]=max (f [ i -1 ][ j ], f [ i-1 ][ j-weight[ i ] ]+ desir[ i ] )。
即判断第i种魅力符取不取,依据取与不取的结果最优来判断,注意 j-weight[ i ]>=0时才有第二项。
内存
用二维数组会占用许多内存,N、M。实际上,从递推公式可以看出,每次循环都只用到了上一行的正上方的值以及左边的值,因此可以定义一维数组,滚动记忆。