洛谷P1509 找啊找啊找GF【DP+二维费用背包】【黄】

Date:2022.02.20
题目描述
sqybi 现在看中了 nn 个 MM,我们不妨把她们编号 11 到 nn。请 MM 吃饭是要花钱的,我们假设请 ii 号 MM 吃饭要花 rmb[i]rmb[i] 块大洋。而希望骗 MM 当自己 GF 是要费人品的,我们假设请第 ii 号 MM 吃饭试图让她当自己 GF 的行为(不妨称作泡该 MM)要耗费 rp[i]rp[i] 的人品。而对于每一个 MM 来说,sqybi 都有一个对应的搞定她的时间,对于第 ii 个 MM 来说叫做 time[i]time[i]。sqybi 保证自己有足够的魅力用 time[i]time[i] 的时间搞定第 ii 个 MM。
sqybi 希望搞到尽量多的 MM 当自己的 GF,这点是毋庸置疑的。但他不希望为此花费太多的时间(毕竟七夕赛的题目还没出),所以他希望在保证搞到 MM 数量最多的情况下花费的总时间最少。
sqybi 现在有 mm 块大洋,他也通过一段时间的努力攒到了 rr 的人品(这次为模拟赛出题也攒 rp 哦~~)。他凭借这些大洋和人品可以泡到一些 MM。他想知道,自己泡到最多的 MM 花费的最少时间是多少。
注意 sqybi 在一个时刻只能去泡一个 MM ——如果同时泡两个或以上的 MM 的话,她们会打起来的…
输入格式
输入的第一行是 nn,表示 sqybi 看中的 MM 数量。
接下来有 nn 行,依次表示编号为 1, 2, 3, \ldots , n1,2,3,…,n 的一个 MM 的信息。每行表示一个 MM 的信息,有三个整数:rmbrmb,rprp 和 timetime。
最后一行有两个整数,分别为 mm 和 rr。
输出格式
你只需要输出一行,其中有一个整数,表示 sqybi 在保证 MM 数量的情况下花费的最少总时间是多少。
输入输出样例
输入 #1复制
4
1 2 5
2 1 6
2 2 2
2 2 3
5 5
输出 #1复制
13
【数据规模】
对于 20% 的数据,1≤n≤10;
对于 100% 的数据,1≤rmb≤100,1≤rp≤100,1≤time≤1000。
对于 100% 的数据,1≤m,r,n≤100。

思路:rmb、rp为二维费用,第一前提是泡最多妹子,因此是二维费用下的最大容量背包问题;第二前提是花时间最少,这个状态伴随着第一前提更新。
代码如下:

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 110,M=1010;
typedef long long LL;
int f[N][M],cnt[N][M],n,m,r,t,a[N],b[N],c[N];
int main()
{
    cin>>t;for(int i=1;i<=t;i++) cin>>a[i]>>b[i]>>c[i];
    cin>>n>>m;
    for(int i=1;i<=t;i++)
        for(int j=n;j>=a[i];j--)
            for(int k=m;k>=b[i];k--)
                if(f[j-a[i]][k-b[i]]+1>f[j][k])
                {
                    f[j][k]=f[j-a[i]][k-b[i]]+1;
                    cnt[j][k]=cnt[j-a[i]][k-b[i]]+c[i];
                }
                else if(f[j-a[i]][k-b[i]]+1==f[j][k])
                    cnt[j][k]=min(cnt[j][k],cnt[j-a[i]][k-b[i]]+c[i]);
    cout<<cnt[n][m];
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值