C~K的奖券(01背包)

本文详细解析了一道经典的01背包问题,通过一个具体的超市兑奖活动案例,讲解了如何利用动态规划算法来求解最优解,即在有限的资源条件下获得最大价值。文章提供了完整的代码实现,并附有清晰的思路说明。

Problem Description

超市举行兑奖活动啦!!!

C~K 费劲心力,终于搞到了 m 张兑奖券,而奖品区有 n 件奖品,分别标号为 1~n,其中第 i 件奖品需要 need(i) 张奖券进行兑换,同时也只能兑换一次,为了辛苦得到的奖券不能够浪费,C~K 给每件奖品都评了分,其中第i件奖品的评分值为 value(i),表示 C~K 对这件奖品的喜好值,现在他想知道,凭借他手上的这些奖券,可以换到哪些奖品,使得这些奖品的喜好值最大。

Input

输入数据有多组(数据组数不超过 100),到 EOF 结束。

每一组测试数据第一行为两个正整数 n, m。表示奖品的个数及 C~K 手中的奖券数。

接下来 n 行描述每一行描述一个奖品,其中第 i 行为两个整数 need(i) 和 value(i),意义如前文所述。

(0 < n <= 500, 0 < m <= 10^5, 0 < need(i) <= 2*10^5, 0 < value(i) <= 10^3)

Output

对于每组输入的数据输出一个整数 ans,代表 C~K可 以获得的总喜好值。

Sample Input

1 3
1 1

Sample Output

1

Hint

Source

【2017年寒假集训 结训赛2】C~K

感慨:刚学习背包的的时候不善于总结,导致比赛的时候卡住了这个模板题,我的天!

思路:01背包放与不放的dp

#include<bits/stdc++.h>
#define mem(x,a) memset(x,a,sizeof(x))
using namespace std;
const int N=100010;
int x[N],v[N],dp[N];

int main()
{
    int n,m;
    while(cin>>n>>m)
    {
        mem(x,0);
        mem(v,0);
        mem(dp,0);
        for(int i=1;i<=n;i++)  
            cin>>x[i]>>v[i]; //x为兑奖券数量,v为喜好值
        for(int i=1;i<=n;i++)
        {
            for(int j=m;j>=1;j--) //01背包倒着枚举所有可能情况
            {
                if(j>=x[i])  //当前情况兑奖券数量充足
                    dp[j]=max(dp[j],dp[j-x[i]]+v[i]);//兑与不兑的最大值
            }
        }
        cout<<dp[m]<<endl; 
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值