Charm Bracelet (北大MOOC程序设计与算法二 第七周题)

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。实际上,从递推公式可以看出,每次循环都只用到了上一行的正上方的值以及左边的值,因此可以定义一维数组,滚动记忆。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章