「背包问题-步入」队伍配置

队伍配置

https://ac.nowcoder.com/acm/contest/24213/1025

题目描述

萌学姐在玩大型手游《futa go》,他现在准备进入作战环节,所以他准备安排自己的队伍。
队伍配置里,可供玩家选择的作战人物被称作“从者”,玩家可以对每个“从者”可以装备至多1件的“概念礼装”,玩家具有一个cost上限值。详细定义如下:
1、 每个从者和概念礼装都具有攻击值ATK。
2、 每个从者和概念礼装都会占据一定的cost值。
3、 每个从者和概念礼装只能上场一次,不能重复使用。
4、 概念礼装只能装备在从者上,不能单独存在。
5、 选择的从者和概念礼装的cost值之和不能超过玩家的cost上限值。
6、 最多可以选择5名从者(在cost值限制下)。
现在给出玩家仓库的每个从者和每件概念礼装的ATK值和cost值,问在满足定义的条件下,队伍可以凑出的最大ATK值

输入描述

第1行输入三个整数n,m,d,代表玩家仓库的从者数量、概念礼装数量和cost上限值。
第2-n+1行,每行输入两个整数a1,b1,表示第i个从者的ATK值和cost值。
第n+2-n+m+1行,每行输入两个整数a2,b2,表示第i个概念礼装的ATK值和cost值。
数据保证:0<n,m≤300,25≤d≤138,1000≤a1≤15488,500≤a2≤2500,3≤b1,b2≤12

输出描述

输出一行,一个整数,代表可以凑出的最大ATK值。

样例

#1

4 2 25
2001 5
2002 5
2003 5
4010 10
2004 10
2005 10
10016

派上前4名从者,最大ATK值=2001+2002+2003+4010=10016(cost总值为25=玩家cost上限)

提示

解析

需要注意以下几点:

  1. 每个从者和礼装只能用一次
  2. 礼装只能给从者使用,不能单独使用
  3. 从者最多只能选择五个(一开始写二维DP没注意这个)
  4. 礼装依附于从者,因此礼装数量一定小于或等于从者(所以我们要先枚举“从者”,后枚举“礼装”)

DP 信息:

  • DP 定义: d p [ i ] [ j ] [ k ] dp[i][j][k] dp[i][j][k] 表示选择 j 个从者和 k 个礼装需要 i 点消耗时 ATK 的最大值。

三维的DP,第一维就是消耗,二维DP则是第二维。

而三维DP的后面两维就是01背包的第一和第二维了。

AC Code

public class Main {
    
    
    public static void main(String[] args) {
    
    
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt(), m = sc.nextInt(), d = sc.nextInt();
        int[][][] dp = new int[200][200][200];
        int ans = 0;
        
        // 只选从者,不选礼装
        for(int i = 1; i <= n; i++) {
    
    
            int w = sc.nextInt(), c = sc.nextInt();
            for(int t = d; t >= c; t--) {
    
    
                for(int k = 1; k <= 5; k++) {
    
    
                    dp[t][k][0] = Math.max(dp[t][k][0], dp[t-c][k-1][0] + w);
                    ans = Math.max(ans, dp[t][k][0]);
                }
            }
        }
        
        // 建立在从者的基础上,再选一个礼装
        for(int i = 1; i <= m; i++) {
    
    
            int w = sc.nextInt(), c = sc.nextInt();
            for(int t = d; t >= c; t--) {
    
    
                for(int k = 1; k <= 5; k++) {
    
    
                    for(int l = 1; l <= k; l++) {
    
    
                        dp[t][k][l] = Math.max(dp[t][k][l], dp[t-c][k][l-1] + w);
                        ans = Math.max(ans, dp[t][k][l]);
                    }
                }
            }
        }
        System.out.println(ans);
    }
}

猜你喜欢

转载自blog.csdn.net/qq_43098197/article/details/130335779