AcWing 5887:拼题A打卡奖励 ← 0-1背包问题

【题目来源】
https://www.acwing.com/problem/content/5890/

【题目描述】
拼题A打卡奖励拼题 A 的教超搞打卡活动,指定了 N 张打卡卷,第 i 张打卡卷需要 mi 分钟做完,完成后可获得 ci 枚奖励的金币。
活动规定每张打卡卷最多只能做一次。
活动总时长为 M 分钟。
请你算出最多可以赢得多少枚金币?

【输入格式】
输入首先在第一行中给出两个正整数 N(≤10^3)和 M(≤365×24×60),分别对应打卡卷的数量和以“分钟”为单位的活动总时长(不超过一年)。
随后一行给出 N 张打卡卷要花费的时间 mi(≤ 600),最后一行给出 N 张打卡卷对应的奖励金币数量 ci(≤ 30)。
上述均为正整数,一行内的数字以空格分隔。

【输出格式】
在一行中输出最多可以赢得的金币数量。

【输入样例】
5 110
70 10 20 50 60
28 1 6 18 22

【输出样例】
40

【样例解释】
选择最后两张卷子,可以在 50+60=110 分钟内获得 18+22=40 枚金币。

【算法分析】
典型的 0-1 背包问题。

【算法代码】

#include <bits/stdc++.h>
using namespace std;

const int N=1e3+5, M=1e6+5;
int dp[M],val[N],vol[N];
int n,m,sum;

int main() {
    cin>>n>>m;
    for(int i=1; i<=n; i++) cin>>val[i];
    for(int i=1; i<=n; i++) {
        cin>>vol[i];
        sum+=vol[i];
    }

    memset(dp,0x3f,sizeof dp);
    dp[0]=0;
    for(int i=1; i<=n; i++) {
        for(int j=sum; j>=vol[i]; j--) {
            dp[j]=min(dp[j],dp[j-vol[i]]+val[i]);
        }
    }

    for(int i=sum; i>=0; i--) {
        if(dp[i]<=m) {
            cout<<i<<endl;
            return 0;
        }
    }
    return 0;
}

/*
in:
5 110
70 10 20 50 60
28 1 6 18 22

out:
40
*/



【参考文献】
https://tiku.scratchor.com/question/view/pdc5fqwzerntfda5
https://pintia.cn/problem-sets/994805046380707840/exam/problems/type/7
https://hexo.ab-in.cn/2022/04/18/GPLT2022-4-18-2/



 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值