为了更好的阅读体检,可以查看我的算法学习网
在线评测链接:P1085
题目内容
塔子哥是一位电脑发烧友,热爱 D I Y DIY DIY组装电脑。他研究了各种零部件,了解到不同型号的零件有不同的性能和价格,而性价比也会有所差异。因此,他需要谨慎地选择零部件,以使他的电脑既具有出色的性能,又不会让他花费太多的钱。
这一次,塔子哥决定升级他的电脑,需要购买 n n n个零件,每个零件有多个型号可供选择。他知道每个型号的价格 a i a_i ai 和性能 v i v_i vi ,并且他有一个限制条件,塔子哥需要每个零件选择一个型号并且总价格不能超过 x x x元。他希望在这个限制条件下,选出的零件能够使他的电脑性能尽可能强大。塔子哥需要你的帮助,来找到最优的选择方案。
输入描述
第一行输入两个正整数 n n n 和 x x x ,代表电脑的零件数量以及塔子哥最大的预算。
接下来的 3 ∗ n 3*n 3∗n 行,每三行用来描述一个零件的不同型号的价格和性能。
对于每种零件,第一行输入一个正数 m m m ,代表该零件有多少种型号;
第二行输入 m m m 个整数,代表这 m m m 个零件的价格;
第三行输入 m m m 个整数,代表这 m m m 个零件的性能。
1 ≤ n , m ≤ 40 1 \leq n,m \leq 40 1≤n,m≤40
1 ≤ a ∗ i , v ∗ i , x ≤ 1 0 9 1 \leq a*_{i},v_*{i},x \leq 10^9 1≤a∗i,v∗i,x≤109
保证所有 m m m 之和不超过 40 40 40 ,即所有零件的型号数量之和不超过 40 40 40 种。
输出描述
如果无法完成组装,则直接输出 − 1 。 -1。 −1。
否则输出一个正整数,代表最终最大的性能。
样例
输入
2 3
2
1 3
2 5
2
2 3
2 4
输出
4
说明
一共需要两个零件。
第一个零件选择第一个型号,第二个零件也选择第一个型号。
这样总价格为 3 3 3 ,总性能为 4 4 4 。
思路:DFS
由题可知,每一种零件都必须选择一个,考虑深搜(dfs)枚举。
具体dfs实现:对于一种零件,循环遍历所有型号,如果说当前所剩下的钱足够买此型号,则递归对下一种零件;否则查看当前零件的下一个型号是否够钱
买。如此递归,直到所有零件都被访问后记录最大性能;
注:在dfs之前,需要把ans初始化为-1,这样做的好处就是如果说没办法递归完所有的零件,则说明无法组装,即ans值不会变
类似题目推荐
CodeFun2000
P1094 2023.03.19-第一题-塔子哥的RBG矩阵
代码
CPP
#include <algorithm>
#include <iostream>
using namespace std;
const int N = 50;
using ll = long long;
ll a[N][N], v[N][N], num[N], ans;
void dfs(int n, ll cost, ll vsum) {
if (n == 0) { // 递归结束条件:遍历完了所有零件
ans = max(ans, vsum); // 记录答案
return;
}
for (int i = 1; i <= num[n]; ++i) {
if (cost >= a[n][i]) { // 如果当前剩下的钱足够购买此型号
dfs(n - 1, cost - a[n][i], vsum + v[n][i]); // 则递归下一个零件
}
}
}
int main() {
int n, x;
cin >> n >> x;
for (int i = 1; i <= n; ++i) {
int m;
cin >> m;
num[i] = m; // 记录当前零件的个数
for (int j = 1; j <= m; ++j) { // 记录价格
cin >> a[i][j];
}
for (int j = 1; j <= m; ++j) { // 记录性能
cin >> v[i][j];
}
}
ans = -1; // 初始化为-1,若dfs不到完所有零件,则ans值不变
dfs(n, x, 0); // 倒过来递归零件,方便处理
cout << ans << endl;
return 0;
}
python
def dfs(n, cost, vsum):
global ans
if n == 0:
ans = max(ans, vsum) # 记录答案
return
for i in range(1, num[n] + 1):
if cost >= a[n][i]:
dfs(n - 1, cost - a[n][i], vsum + v[n][i]) # 递归下一个零件
N=50
n, x = map(int, input().split())
a = [[0] * N for _ in range(N)] # 零件价格
v = [[0] * N for _ in range(N)] # 零件性能
num = [0] * N # 每种零件的个数
ans = -1 # 最终答案
for i in range(1, n + 1):
m = int(input()) # 输入当前零件个数
num[i] = m # 记录当前零件的个数
a[i][1 : m + 1] = map(int, input().split()) # 输入价格
v[i][1 : m + 1] = map(int, input().split()) # 输入性能
dfs(n, x, 0) # 逆序递归零件
print(ans) # 打印最终答案
Java
import java.util.Scanner;
public class Main {
static final int N = 50;
static long[][] a = new long[N][N]; // 零件价格
static long[][] v = new long[N][N]; // 零件性能
static int[] num = new int[N]; // 每种零件的个数
static long ans; // 最终答案
public static void dfs(int n, long cost, long vsum) {
if (n == 0) {
ans = Math.max(ans, vsum); // 记录答案
return;
}
for (int i = 1; i <= num[n]; i++) {
if (cost >= a[n][i]) {
dfs(n - 1, cost - a[n][i], vsum + v[n][i]); // 递归下一个零件
}
}
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int x = scanner.nextInt();
for (int i = 1; i <= n; i++) {
int m = scanner.nextInt(); // 输入当前零件个数
num[i] = m; // 记录当前零件的个数
for (int j = 1; j <= m; j++) {
a[i][j] = scanner.nextLong(); // 输入价格
}
for (int j = 1; j <= m; j++) {
v[i][j] = scanner.nextLong(); // 输入性能
}
}
ans = -1; // 初始化答案为 -1
dfs(n, x, 0); // 逆序递归零件
System.out.println(ans); // 打印最终答案
}
}
Go
package main
import (
"fmt"
)
const N = 50
var a [N][N]int64 // 零件价格
var v [N][N]int64 // 零件性能
var num [N]int // 每种零件的个数
var ans int64 // 最终答案
func dfs(n int, cost int64, vsum int64) {
if n == 0 {
ans = max(ans, vsum) // 记录答案
return
}
for i := 1; i <= num[n]; i++ {
if cost >= a[n][i] {
dfs(n-1, cost-a[n][i], vsum+v[n][i]) // 递归下一个零件
}
}
}
func max(a, b int64) int64 {
if a > b {
return a
}
return b
}
func main() {
var n, x int
fmt.Scan(&n, &x) // 输入 n 和 x
for i := 1; i <= n; i++ {
var m int
fmt.Scan(&m) // 输入当前零件个数
num[i] = m // 记录当前零件的个数
for j := 1; j <= m; j++ {
fmt.Scan(&a[i][j]) // 输入价格
}
for j := 1; j <= m; j++ {
fmt.Scan(&v[i][j]) // 输入性能
}
}
ans = -1 // 初始化答案为 -1
dfs(n, int64(x), 0) // 逆序递归零件
fmt.Println(ans) // 打印最终答案
}
Js
process.stdin.resume();
process.stdin.setEncoding('utf-8');
let input = '';
process.stdin.on('data', (data) => {
input += data;
return;
});
process.stdin.on('end', () => {
const lines = input.trim().split('\n');
const N = 50;
const num = new Array(N).fill(0); // 每种零件的个数
const a = new Array(N).fill().map(() => new Array(N).fill(0)); // 零件价格
const v = new Array(N).fill().map(() => new Array(N).fill(0)); // 零件性能
let ans = -1; // 初始化为-1,若dfs不到完所有零件,则ans值不变
let n, x;
let idx=0;
[n, x] = lines[0].trim().split(' ').map(Number);
for (let i=1;i<=n;i++){
num[i]=Number(lines[++idx]);
let tmp=lines[++idx].split(' ').map(Number);
for (let j=1;j<=num[i];j++)
a[i][j]=tmp[j-1];
tmp=lines[++idx].split(' ').map(Number);
for (let j=1;j<=num[i];j++)
v[i][j]=tmp[j-1];
}
dfs(n, x, 0); // 逆序递归零件
console.log(ans); // 打印最终答案
// 定义 dfs() 函数以及其他函数
function dfs(n, cost, vsum) {
if (n === 0) {
ans = Math.max(ans, vsum); // 记录答案
return;
}
for (let i = 1; i <= num[n]; ++i) {
if (cost >= a[n][i]) {
dfs(n - 1, cost - a[n][i], vsum + v[n][i]); // 递归下一个零件
}
}
}
});
题目内容均收集自互联网,如如若此项内容侵犯了原著者的合法权益,可联系我: (CSDN网站注册用户名: 塔子哥学算法) 进行删除。