AcWing 1022. 宠物小精灵之收服 0/1 背包的二维费用

1022. 宠物小精灵之收服

  • 0/1 背包的二维费用的问题

分析

  • 条件:野生小精灵总数 (大小为 K K K

  • 花费1:精灵球的数量(大小为 N N N

  • 花费2:皮卡丘的体力值 (大小为 M M M

  • 价值:小精灵的数量,每个都表示为 1 1 1

  • 状态表示: f [ i , j , k ] f[i,j,k] f[i,j,k] 表示所有只从前 i i i 个物品中选择,且花费1不超过 j j j,花费2不超过 k k k 的选法的最大价值(也就是最大数量)

  • 状态计算: f [ i , j , k ] = m a x ( f [ i − 1 , j , k ] , f [ i , j − c o s t 1 [ i ] , k − c o s t 2 [ i ] ] + 1 ) f[i,j,k]=max(f[i-1,j,k],f[i,j-cost_1[i],k-cost_2[i]]+1) f[i,j,k]=max(f[i1,j,k],f[i,jcost1[i],kcost2[i]]+1)

    • 分别表示选择第 i i i 个物品和不选
  • 求最后一步:最多可以收服的小精灵数量为 f [ K , N , M ] f[K,N,M] f[K,N,M]

实现细节

  • 在本题中,我们需要得到的答案是在所有满足的答案中,取到 k k k 的最小值,所以我们还要在 f f f 的第一维和第二维等于 K , N K,N K,N 的时候遍历 k = i → M k=i\to M k=iM 并换算成剩余体力,求出答案
  • 要注意皮卡丘的体力为 0 0 0 时,小精灵不能被收服,所以最多可以收服的小精灵数量实际上为 f [ K , N , M − 1 ] f[K,N,M-1] f[K,N,M1]

Code

#include <bits/stdc++.h>

using namespace std;
const int maxn = 1500;

int n, V1, V2;
int f[maxn][maxn];
int main() {
	scanf("%d%d%d", &V1, &V2, &n);
	for(int i = 0; i < n; i++) {
		int vol1, vol2;
		scanf("%d%d", &vol1, &vol2);
		for(int j = V1; j >= vol1; j--) {
			for(int k = V2 - 1; k >= vol2; k--) { //体力不能为0 
				f[j][k] = max(f[j][k], f[j - vol1][k - vol2] + 1);
			}
		}
	}

	printf("%d ", f[V1][V2 - 1]);

	int k = V2 - 1;
	while(k > 0 && f[V1][k - 1] == f[V1][V2 - 1]) k--;
	printf("%d", V2 - k);

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值