第九章 动态规划-1269:【例9.13】庆功会

1269:【例9.13】庆功会

时间限制: 1000 ms 内存限制: 65536 KB
提交数: 8343 通过数: 4803
【题目描述】
为了庆贺班级在校运动会上取得全校第一名成绩,班主任决定开一场庆功会,为此拨款购买奖品犒劳运动员。期望拨款金额能购买最大价值的奖品,可以补充他们的精力和体力。

【输入】
第一行二个数n(n≤500),m(m≤6000),其中n代表希望购买的奖品的种数,m表示拨款金额。

接下来n行,每行3个数,v、w、s,分别表示第I种奖品的价格、价值(价格与价值是不同的概念)和能购买的最大数量(买0件到s件均可),其中v≤100,w≤1000,s≤10。

【输出】
一行:一个数,表示此次购买能获得的最大的价值(注意!不是价格)。

【输入样例】
5 1000
80 20 4
40 50 9
30 50 7
40 30 6
20 20 1
【输出样例】
1040


思路:二进制优化,1~ m可以用这些数的组合构成: 1 2 4 8…2^x (+ 剩余的数)。1到n以内的数字,能够通过 n 内的进制数组合得到,比如 9以内的二进制数有 1 2 4 8,可以自己试一下, 3 = 1 + 2 ,5=1 + 4 ,6= 2 + 4,所以,我们可以利用二进制数的拆分求出所有 n 以内的数;拆分的过程:9 - 1 = 8; 8 - 2 = 6; 6 - 4 = 2 ; 2 - 8 < 0; 那么要求的 9 以内的二进制数就是 1,2, 4,2,这几个二进制是能够组成 9以内包括 9 的所有整数,然后通过 w[ i ] 乘以这些二进制数,把他们当作一件物品来做01背包的处理,当然,如果没有用二进制拆分的话就用朴素方法来做。二进制优化,简单来说,就是把一个数字分成 (1 2 4 8…最大数) 这样下去的类型为什么呢? 因为这些数字可以组成(1~最大数)中的任何一个数我们可以实现组合把这些抽出来变成一个新的产品,不过 重量和价值 有所不同。变成:
一件 v[i]*1 , w[i]*1

一件 v[i]*2 , w[i]*2

一件 v[i]*4 , w[i]*4

一件 v[i]*8 , w[i]*8

#include <iostream>
#include <cstdio>
using namespace std;

#define N 10000
int c[N], w[N], num[N];
int f[N], new_c[N], new_w[N];
int v, m, tot;
int main() 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值