小欧逛商店
[题目链接](https://www.nowcoder.com/practice/919086dc716a466ba8284d5c749e8c15)
思路
本题是一道模拟/贪心题。小欧按从左到右的顺序逛商店,每遇到一个商品就判断背包剩余容量是否能装下:
- 如果当前商品的体积
剩余容量,就买下它,剩余容量减少,总价值增加。
- 如果装不下,就跳过这个商品。
注意:小欧是贪心地按顺序购买,不是经典的 0-1 背包求最优解。只需按顺序扫描一遍即可。
注意事项
数据范围中商品数量可达 ,价值可达
,因此总价值可能达到
级别,超过 32 位整数范围。C++ 中需要使用
long long,Java 中需要使用 long。
举例
以样例 n=3, cap=5 为例:
| 商品 | 体积 | 价值 | 剩余容量 | 操作 | 总价值 |
|---|---|---|---|---|---|
| 1 | 4 | 3 | 5 | 买入,容量变为 1 | 3 |
| 2 | 2 | 5 | 1 | 装不下,跳过 | 3 |
| 3 | 1 | 3 | 1 | 买入,容量变为 0 | 6 |
最终答案为 。
代码
#include <iostream>
using namespace std;
int main() {
long long n, cap;
cin >> n >> cap;
long long totalValue = 0;
for (long long i = 0; i < n; i++) {
long long v, w;
cin >> v >> w;
if (v <= cap) {
cap -= v;
totalValue += w;
}
}
cout << totalValue << endl;
return 0;
}
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
long cap = sc.nextLong();
long totalValue = 0;
for (int i = 0; i < n; i++) {
long v = sc.nextLong();
long w = sc.nextLong();
if (v <= cap) {
cap -= v;
totalValue += w;
}
}
System.out.println(totalValue);
}
}
n, cap = map(int, input().split())
total = 0
for _ in range(n):
v, w = map(int, input().split())
if v <= cap:
cap -= v
total += w
print(total)
const readline = require('readline');
const rl = readline.createInterface({ input: process.stdin });
const lines = [];
rl.on('line', line => lines.push(line.trim()));
rl.on('close', () => {
const [n, cap] = lines[0].split(' ').map(Number);
let remaining = cap;
let total = 0;
for (let i = 1; i <= n; i++) {
const [v, w] = lines[i].split(' ').map(Number);
if (v <= remaining) {
remaining -= v;
total += w;
}
}
console.log(total);
});
复杂度
- 时间复杂度:
,只需遍历一次所有商品。
- 空间复杂度:
,只使用常数个变量。

京公网安备 11010502036488号