acwing 1022 宠物小精灵

题面

在这里插入图片描述

题解(二维费用01背包)

花费1 : 精灵球数量
花费2 :皮卡丘体力值
价值 :小精灵的数量(每只精灵价值为1)
状态表示 :f [ i , j , k ] 表示所有只考虑前i个物品,且花费1不超过 j,花费2不超过k的选法的最大值
状态计算:f[ i , j , k ] = Max( f [ i - 1 , j , k ] , f [ i - 1 , j - v1 [ i ],k - v2 [ i ] ] + 1)
注意:题目说道:使得皮卡丘体力小于等于0的野生小精灵也不会被小智收服,因此皮卡丘的体力值需在V2 - 1时开始
时间复杂度 : O( K N M )

代码

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>

using namespace std;
const int maxn = 1010;

//精灵球数量,皮卡丘初始体力
int N, M, K;
//从前i个物品中选,花费1(精灵球数量)不超过j,花费2(皮卡丘体力值)不超过k选法的最大值
int f[maxn][maxn];

int main() {
    
    

    cin >> N >> M >> K;
    for (int i = 1; i <= K; i++) {
    
    
        int v1, v2;
        cin >> v1 >> v2;
        for (int j = N; j >= v1; j--) {
    
    
            for (int k = M - 1; k >= v2; k--) {
    
    
                f[j][k] = max(f[j][k], f[j - v1][k - v2] + 1);
            }
        }
    }

    int minn = 0;  //找一个价值和f[N][M-1]一样,但消耗体力最小的
    for (int i = 0; i <= M - 1; i++) {
    
    
        if (f[N][M - 1] == f[N][i]) {
    
    
            minn = i;
            break;
        }
    }
    cout << f[N][M - 1] << " " << M - minn << endl;

    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_44791484/article/details/115249988