洛谷的运营组决定,如果一名oier向他的教练推荐洛谷,并能够成功的使用(成功使用的定义是:该团队有20个或以上的成员,上传10道以上的私有题目,布置过一次作业并成功举办过一次公开比赛),那么他可以浪费掉kkksc03的一些时间的同时消耗掉kkksc03的一些金钱以满足自己的一个愿望。
Kkksc03的时间和金钱是有限的,所以他很难满足所有同学的愿望。所以他想知道在自己的能力范围内,最多可以完成多少同学的愿望?
输入输出格式
输入格式:
第一行,n M T,表示一共有n(n<=100)个愿望,kkksc03 的手上还剩M(M<=200)元,他的暑假有T(T<=200)分钟时间。
第2~n+1行 mi,ti 表示第i个愿望所需要的时间和金钱。
输出格式:
一行,一个数,表示kkksc03最多可以实现愿望的个数。
扫描二维码关注公众号,回复:
2755575 查看本文章
输入输出样例
输入样例#1: 复制
6 10 10 1 1 2 3 3 2 2 5 5 2 4 3
输出样例#1: 复制
4
说明
提示 第1,2,3,6个
思路:刚学dp,看着像01背包就瞎搞了,没想到过了.....过了(开心),其实这是一道01背包的变形,即往一个有两个容量的背包里塞东西求塞的最大个数,我们假设dp[ i ][ j ][ k ]表示前 i 个愿望金钱 为 j 时间为 k 最多实现愿望的个数,如果
j < a[i] (第i个愿望花费金钱)或 k < b[ i ] (第 i 个愿望花费时间)则状态不变即 dp[ i ][ j ][ k ] = dp[ i - 1][ j ][ k ]
否则 dp[i][j][k] = max(dp[i - 1][j][k],dp[i - 1][j - a[i]][k - b[i]] + 1)
ok,状态转移方程已经推出来了,就很简单啦
代码;
#include<bits/stdc++.h>
using namespace std;
const int maxn = 210;
int dp[105][maxn][maxn];
int a[110],b[105];
int main()
{
int n,m,t;
scanf("%d %d %d",&n,&m,&t);
for (int i = 1;i <= n;i ++)
scanf("%d %d",&a[i],&b[i]);
for (int i = 1;i <= n;i ++)
for (int j = 1;j <= m;j ++)
for (int k = 1;k <= t;k ++)
if (j < a[i] || k < b[i])
dp[i][j][k] = dp[i - 1][j][k];
else
dp[i][j][k] = max(dp[i - 1][j][k],dp[i - 1][j - a[i]][k - b[i]] + 1);
printf("%d\n",dp[n][m][t]);
return 0;
}