luogu P1509 找啊找啊找GF |背包

题目背景

sqybi现在看中了n个MM,我们不妨把她们编号1到n.请MM吃饭是要花钱的,我们假设请i号MM吃饭要花rmb[i]块大洋.而希望骗MM当自己GF是要费人品的,我们假设请第i号MM吃饭试图让她当自己GF的行为(不妨称作泡该MM)要耗费rp[i]的人品.而对于每一个MM来说,sqybi都有一个对应的搞定她的时间,对于第i个MM来说叫做time[i]. sqybi保证自己有足够的魅力用time[i]的时间搞定第i个MM_.

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

题目描述

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

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

输入格式

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

接下来有n行,依次表示编号为1, 2, 3, ..., n的一个MM的信息.每行表示一个MM的信息,有三个整数:rmb, rp和time.

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

输出格式

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

.

背包问题,但是有两个限制

在原来基础上增加一维进行转移就行了

保证MM最多情况下再去让时间最小

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define int long long
using namespace std;
const int N=105;
int a[N],b[N],val[N],f[N][N],dp[N][N];
signed main(){
	int n,m,r;
	cin>>n;
	for(int i=1;i<=n;i++)
	scanf("%lld%lld%lld",&a[i],&b[i],&val[i]);
	cin>>m>>r;
	for(int i=1;i<=n;i++){
		for(int j=m;j>=a[i];j--)
		for(int k=r;k>=b[i];k--)
		if(dp[j][k]<dp[j-a[i]][k-b[i]]+1){
			dp[j][k]=dp[j-a[i]][k-b[i]]+1;
			f[j][k]=f[j-a[i]][k-b[i]]+val[i];
		}else if(dp[j][k]==dp[j-a[i]][k-b[i]]+1)
		f[j][k]=min(f[j][k],f[j-a[i]][k-b[i]]+val[i]);
	}
	cout<<f[m][r]<<endl;
}