测评会员优惠活动进行中 · 开通 VIP,有效期内测评不限次 VIP 优惠中 · 测评不限次 立即查看

A31423. 拼题A打卡奖励

填空题 较难

题目描述

拼题A打卡奖励

题目描述

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

输入格式

输入首先在第一行中给出两个正整数 N(≤103) 和 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 枚金币。

参考答案

#include <iostream> using namespace std; const int N = 1e3 + 10, M = 365 * 24 * 60 + 10; int n, m; int v[N], w[N]; int dp[M]; int gcd(int a, int b) { return b ? gcd(b, a % b) : a; } int main() { cin >> n >> m; cin >> v[0]; int yuanzi = v[0]; for (int i = 1; i < n; i ++ ) { cin >> v[i]; yuanzi = gcd(v[i], yuanzi); } for (int i = 0; i < n; i ++ ) cin >> w[i]; for (int i = 0; i < n; i ++ ) { int cnt = 0; for (int j = m; j >= v[i]; j -= yuanzi ) { if (dp[j - v[i]] + w[i] > dp[j]) dp[j] = dp[j - v[i]] + w[i]; else cnt ++; if (cnt == 10) break; } } cout << dp[m] << endl; }
上一题 下一题