P1509 找啊找啊找GF 题解

题目内容

题目链接

题目背景

“找啊找啊找 GF,找到一个好 GF,吃顿饭啊拉拉手,你是我的好 GF。再见。”

“诶,别再见啊…”

七夕… 七夕… 七夕这个日子,对于 sqybi 这种单身的菜鸟来说是多么的痛苦… 虽然他听着这首叫做“找啊找啊找 GF”的歌,他还是很痛苦。为了避免这种痛苦,sqybi 决定要给自己找点事情干。他去找到了七夕模拟赛的负责人 zmc MM,让她给自己一个出题的任务。经过几天的死缠烂打,zmc MM 终于同意了。

题目描述

但是,拿到这个任务的 sqybi 发现,原来出题比单身更让人感到无聊 -_- … 所以,他决定了,要在出题的同时去办另一件能够使自己不无聊的事情——给自己找 GF。
sqybi 现在看中了 n n n 个 MM,我们不妨把她们编号 1 1 1 n n n。请 MM 吃饭是要花钱的,我们假设请 i i i 号 MM 吃饭要花 r m b [ i ] rmb[i] rmb[i] 块大洋。而希望骗 MM 当自己 GF 是要费人品的,我们假设请第 i i i 号 MM 吃饭试图让她当自己 GF 的行为(不妨称作泡该 MM)要耗费 r p [ i ] rp[i] rp[i] 的人品。而对于每一个 MM 来说,sqybi 都有一个对应的搞定她的时间,对于第 i i i 个 MM 来说叫做 t i m e [ i ] time[i] time[i]。sqybi 保证自己有足够的魅力用 t i m e [ i ] time[i] time[i] 的时间搞定第 i i i 个 MM _

sqybi 希望搞到尽量多的 MM 当自己的 GF,这点是毋庸置疑的。但他不希望为此花费太多的时间(毕竟七夕赛的题目还没出),所以他希望在保证搞到 MM 数量最多的情况下花费的总时间最少。

sqybi 现在有 m m m 块大洋,他也通过一段时间的努力攒到了 r r r 的人品(这次为模拟赛出题也攒 rp 哦~~)。他凭借这些大洋和人品可以泡到一些 MM。他想知道,自己泡到最多的 MM 花费的最少时间是多少。

注意 sqybi 在一个时刻只能去泡一个 MM ——如果同时泡两个或以上的 MM 的话,她们会打起来的…

输入格式

输入的第一行是 n n n,表示 sqybi 看中的 MM 数量。

接下来有 n n n 行,依次表示编号为 1 , 2 , 3 , … , n 1,2,3,…,n 1,2,3,,n 的一个 MM 的信息。每行表示一个 MM 的信息,有三个整数: r m b rmb rmb r p rp rp t i m e time time

最后一行有两个整数,分别为 m m m r r r

输出格式

你只需要输出一行,其中有一个整数,表示 sqybi 在保证 MM 数量的情况下花费的最少总时间是多少。

样例

输入数据 1

4
1 2 5
2 1 6
2 2 2
2 2 3
5 5

输出数据 1

13

题解

思路:
一个简单(吗?)的 01 背包,把 GF 的个数和花费时间分成两个 DP 数组。
状态转移方程为:
{ d p _ n u m [ j ] [ k ] < d p _ n u m [ j − r m b [ i ] ] [ k − r p [ i ] ] + 1 d p _ n u m + 1 ,   d p _ t i m e [ j ] [ k ] = d p _ t i m e [ j − r m b [ i ] ] [ k − r p [ i ] ] + t [ i ] d p _ n u m [ j ] [ k ] = d p _ n u m [ j − r m b [ i ] ] [ k − r p [ i ] ] + 1 d p _ t i m e [ j ] [ k ] = min ⁡ ( d p _ t i m e [ j ] [ k ] , d p _ t i m e [ j − r m b [ i ] ] [ k − r p [ i ] ] + t [ i ] ) \begin{cases} dp\_num[j][k] < dp\_num[j - rmb[i]][k - rp[i]] + 1 & dp\_num+1,\ dp\_time[j][k] = dp\_time[j - rmb[i]][k - rp[i]] + t[i] \\ dp\_num[j][k] = dp\_num[j - rmb[i]][k - rp[i]] + 1 & dp\_time[j][k] = \min(dp\_time[j][k], dp\_time[j - rmb[i]][k - rp[i]] + t[i]) \end{cases} {dp_num[j][k]<dp_num[jrmb[i]][krp[i]]+1dp_num[j][k]=dp_num[jrmb[i]][krp[i]]+1dp_num+1, dp_time[j][k]=dp_time[jrmb[i]][krp[i]]+t[i]dp_time[j][k]=min(dp_time[j][k],dp_time[jrmb[i]][krp[i]]+t[i])
最后输出 d p _ t i m e [ m ] [ r ] dp\_time[m][r] dp_time[m][r] 即可。

#include <bits/stdc++.h>
using namespace std;
int n, m, r;
int rmb[105], rp[105], t[105]; // 这里要把 time 改成 t,不然会编译错误
int dp1[105][105], dp2[105][105]; // dp1 为 dp_num,dp2 为 dp_time
int main() {
	cin >> n;
	for (int i = 1; i <= n; i++) cin >> rmb[i] >> rp[i] >> t[i];
	cin >> m >> r; // 坑点1:m、r 不是和 n 一起读入的
	for (int i = 1; i <= n; i++) {
		for (int j = m; j >= rmb[i]; j--) {
			for (int k = r; k >= rp[i]; k--) {
				if (dp1[j][k] < dp1[j - rmb[i]][k - rp[i]] + 1) { // 坑点2:这里判断时要注意 +1
					dp1[j][k]++;
					dp2[j][k] = dp2[j - rmb[i]][k - rp[i]] + t[i];
				} else if (dp1[j][k] == dp1[j - rmb[i]][k - rp[i]] + 1) 
					dp2[j][k] = min(dp2[j][k], dp2[j - rmb[i]][k - rp[i]] + t[i]);
			}
        }
    }
	cout << dp2[m][r] << endl;
    return 0;
}

谢 谢 观 看 \textcolor{red}{\huge{\text{谢}}}\textcolor{#F8F800}{\huge{\text{谢}}}\textcolor{green}{\huge{\text{观}}}\textcolor{#3F7FFF}{\huge{\text{看}}}

  • 9
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值