洛谷P1855 榨取kkksc03 01背包

洛谷的运营组决定,如果一名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最多可以实现愿望的个数。

 

输入输出样例

输入样例#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;
} 

 

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页