poj 4131:Charm Bracelet 动规

题目

总时间限制: 1000ms 内存限制: 65536kB
描述
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

思路

动规题目,首先找到子问题。要解决的问题是N个物品,限重M,求价值最大。可以考虑某一个物品是否选中的最大值,即

  1. 该物品选中:该物品的价值加上剩下N-1个物品的最大价值
  2. 该物品没选中:剩下N-1个物品的最大价值。

其中,第一种需要考虑剩下N-1种物品的限重也是减小的。

递推公式: V _ M A X [ i , j ] = M A X ( V _ M A X [ i − 1 , j ] , V _ M A X [ i − 1 , j − w [ i ] ] + d [ i ] ) V\_MAX[i,j] = MAX(V\_MAX[i-1,j],V\_MAX[i-1,j-w[i]]+d[i]) V_MAX[i,j]=MAX(V_MAX[i1,j],V_MAX[i1,jw[i]]+d[i]) ,其中 V _ M A X [ i , j ] V\_MAX[i,j] V_MAX[i,j]是第一i物品限重为j时的最大值, w [ i ] w[i] w[i]是第i个物品的质量 , d [ i ] d[i] d[i]是第i个物品的价值。 V _ M A X [ i − 1 , j ] V\_MAX[i-1,j] V_MAX[i1,j]是不选第i个物品,价值为前 i − 1 i-1 i1个限重为 j j j时的价值; V _ M A X [ i − 1 , j − w [ i ] ] + d [ i ] V\_MAX[i-1,j-w[i]]+d[i] V_MAX[i1,jw[i]]+d[i]是选第 i i i个物品限重为 j j j的价值,这里是减是因为限重是已经固定的,所以只能是调整前 i − 1 i-1 i1个物品的质量,如果是加的话,限重就不是 j j j

该题由于数组太大,内存限制会超,故使用滚动数组记录,只保留一个一维数组来记录

#include <stdio.h>
#include<algorithm>
int N,M;
int w[3405];
int d[3405];
int lo[12880];
using namespace std;

int main()
{
   scanf("%d%d",&N,&M);
   for(int i=0;i<N;i++){
       scanf("%d%d",&(w[i]),&(d[i]));
   }
   for(int i=0;i<N;i++){
    for(int j=M;j>=w[i];j--){
        lo[j] = max(lo[j],lo[j-w[i]]+d[i]);
    }
   }

   printf("%d",lo[M]);
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值