(A卷,200分)- 查找充电设备组合(Java & JS & Python)

题目描述

某个充电站,可提供n个充电设备,每个充电设备均有对应的输出功率。任意个充电设备组合的输出功率总和,均构成功率集合P的1个元素。功率集合P的最优元素,表示最接近充电站最大输出功率p_max的元素。

输入描述

输入为3行:

  • 第1行为充电设备个数n
  • 第2行为每个充电设备的输出功率
  • 第3行为充电站最大输出功率p_max

输出描述

功率集合P的最优元素

备注

  • 充电设备个数 n > 0
  • 最优元素必须小于或等于充电站最大输出功率p_max

用例

输入 4
50 20 20 60
90
输出 90
说明 当充电设备输出功率50、20、20组合时,其输出功率总和为90,最接近充电站最大充电输出功率,因此最优元素为90。
输入 2
50 40
30
输出 0
说明 所有充电设备的输出功率组合,均大于充电站最大充电输出功率30,此时最优元素值为0。

题目解析

本题可以当成01背包问题处理。其中:

第3行充电站最大输出功率p_max  可以当成  背包承重

第2行每个充电设备的输出功率  可以当成  不同物品的重量以及价值,即重量=价值

现在要求:背包承重下能装入的最大价值。

关于01背包问题,大家可以看

01背包二维数组解法

JavaScript算法源码

/* JavaScript Node ACM模式 控制台输入获取 */
const readline = require("readline");

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
});

const lines = [];
rl.on("line", (line) => {
  lines.push(line);

  if (lines.length === 3) {
    const n = lines[0] - 0;
    const p = lines[1].split(" ").map(Number);
    const p_max = lines[2] - 0;

    console.log(getResult(n, p, p_max));
    lines.length = 0;
  }
});

function getResult(n, p, p_max) {
  const dp = new Array(n + 1).fill(0).map(() => new Array(p_max + 1).fill(0));

  for (let i = 0; i <= n; i++) {
    for (let j = 0; j <= p_max; j++) {
      if (i === 0 || j === 0) continue;

      // 注意这里p[i-1]中i-1不会越界,因为i=0时不会走到这一步,另外i-1是为了防止尾越界,因为dp矩阵的行数是n+1,因此p[i]可能会尾越界,而p[i-1]就不会越界了
      if (p[i - 1] > j) {
        dp[i][j] = dp[i - 1][j];
      } else {
        dp[i][j] = Math.max(dp[i - 1][j], p[i - 1] + dp[i - 1][j - p[i - 1]]);
      }
    }
  }

  return dp[n][p_max];
}

Java算法源码

import java.util.Scanner;

public class Main {
  public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);

    int n = sc.nextInt();

    int[] p = new int[n];
    for (int i = 0; i < n; i++) {
      p[i] = sc.nextInt();
    }

    int p_max = sc.nextInt();

    System.out.println(getResult(n, p, p_max));
  }

  public static int getResult(int n, int[] p, int p_max) {
    int[][] dp = new int[n + 1][p_max + 1];

    for (int i = 0; i <= n; i++) {
      for (int j = 0; j <= p_max; j++) {
        if (i == 0 || j == 0) continue;

        // 注意这里p[i-1]中i-1不会越界,因为i=0时不会走到这一步,另外i-1是为了防止尾越界,因为dp矩阵的行数是n+1,因此p[i]可能会尾越界,而p[i-1]就不会越界了
        if (p[i - 1] > j) {
          dp[i][j] = dp[i - 1][j];
        } else {
          dp[i][j] = Math.max(dp[i - 1][j], p[i - 1] + dp[i - 1][j - p[i - 1]]);
        }
      }
    }

    return dp[n][p_max];
  }
}

Python算法源码

n = int(input())
p = list(map(int, input().split()))
p_max = int(input())

dp = [[0 for i in range(p_max + 1)] for j in range(n + 1)]

for i in range(n + 1):
    for j in range(p_max + 1):
        if i == 0 or j == 0:
            continue

        if p[i - 1] > j:
            dp[i][j] = dp[i - 1][j]
        else:
            dp[i][j] = max(dp[i - 1][j], p[i - 1] + dp[i - 1][j - p[i - 1]])

print(dp[n][p_max])

01背包滚动数组优化解法

关于01背包的滚动数组优化解法请看:算法设计 – 01背包问题的状态转移方程优化,以及完全背包问题_01背包问题状态转移方程_伏城之外的博客-CSDN博客

 Java算法源码

import java.util.Scanner;

public class Main {
  public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);

    int n = sc.nextInt();

    int[] p = new int[n + 1];
    for (int i = 1; i <= n; i++) {
      p[i] = sc.nextInt();
    }

    int p_max = sc.nextInt();

    System.out.println(getResult(n, p, p_max));
  }

  public static int getResult(int n, int[] p, int p_max) {
    // 01背包滚动数组优化解法
    int[] dp = new int[p_max + 1];

    for (int i = 1; i <= n; i++) {
      // 注意使用滚动数组优化时,关于背包承重的遍历应该倒序
      for (int j = p_max; j >= p[i]; j--) {
        dp[j] = Math.max(dp[j], dp[j - p[i]] + p[i]);
      }
    }

    return dp[p_max];
  }
}

JavaScript算法源码

/* JavaScript Node ACM模式 控制台输入获取 */
const readline = require("readline");

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
});

const lines = [];
rl.on("line", (line) => {
  lines.push(line);

  if (lines.length === 3) {
    const n = lines[0] - 0;
    const p = lines[1].split(" ").map(Number);
    const p_max = lines[2] - 0;

    console.log(getResult(n, p, p_max));
    lines.length = 0;
  }
});

function getResult(n, p, p_max) {
  p = [0, ...p];

  // 01背包滚动数组优化解法
  const dp = new Array(p_max + 1).fill(0);

  for (let i = 1; i <= n; i++) {
    // 注意使用滚动数组优化时,关于背包承重的遍历应该倒序
    for (let j = p_max; j >= p[i]; j--) {
      dp[j] = Math.max(dp[j], dp[j - p[i]] + p[i]);
    }
  }

  return dp[p_max];
}

Python算法源码

# 输入获取
n = int(input())
p = list(map(int, input().split()))
p_max = int(input())


# 算法入口
def getResult(n, p, p_max):
    p.insert(0, 0)

    # 01背包滚动数组优化解法
    dp = [0 for _ in range(p_max + 1)]

    for i in range(1, n + 1):
        # 注意使用滚动数组优化时,关于背包承重的遍历应该倒序
        for j in range(p_max, p[i] - 1, -1):
            dp[j] = max(dp[j], dp[j - p[i]] + p[i])

    print(dp[p_max])


# 算法调用
getResult(n, p, p_max)

免责声明:

1、IT资源小站为非营利性网站,全站所有资料仅供网友个人学习使用,禁止商用
2、本站所有文档、视频、书籍等资料均由网友分享,本站只负责收集不承担任何技术及版权问题
3、如本帖侵犯到任何版权问题,请立即告知本站,本站将及时予与删除下载链接并致以最深的歉意
4、本帖部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责
5、一经注册为本站会员,一律视为同意网站规定,本站管理员及版主有权禁止违规用户
6、其他单位或个人使用、转载或引用本文时必须同时征得该帖子作者和IT资源小站的同意
7、IT资源小站管理员和版主有权不事先通知发贴者而删除本文

0

评论0

站点公告

没有账号?注册  忘记密码?