T1. 圣诞老人的礼物
圣诞节来临了,在城市 A 中圣诞老人准备分发糖果,现在有多箱不同的糖果,每箱糖果有自己的价值和重量,每箱糖果都可以拆分成任意散装组合带走。圣诞老人的驯鹿最多只能承受一定重量的糖果,请问圣诞老人最多能带走多大价值的糖果。
时间限制:1 s
内存限制:64 MB
- 输入
第一行由两个部分组成,分别为糖果箱数正整数 n ( 1 ≤ n ≤ 100 ) n\ (1\le n\le 100) n (1≤n≤100),驯鹿能承受的最大重量正整数 w ( 0 < w < 10000 ) w\ (0 < w < 10000) w (0<w<10000),两个数用空格隔开。其余 n n n 行每行对应一箱糖果,由两部分组成,分别为一箱糖果的价值正整数 v v v 和重量正整数 w w w,中间用空格隔开。 - 输出
输出圣诞老人能带走的糖果的最大总价值,保留 1 1 1 位小数。输出为一行,以换行符结束。 - 样例输入
4 15 100 4 412 8 266 7 591 2
- 样例输出
1193.0
思路分析
此题考查贪心算法中的部分背包问题,属于基础题。
由于糖果可以拆分,因此背包必定可以装满。要想最终总价值最大,容易想到优先装入性价比最高的糖果,每一步决策后的结果都是当前最优解。
可以采用反证法证明该策略的正确性,即假设该策略不是最优的,那么优先装入性价比较低的糖果:
- 在同等重量下,新策略可以获得的总价值并非当前最优;
- 在同等价值下,新策略的糖果总重量更重,那么后续选择的冗余空间更小,不能使结果更优,甚至可能变劣。
因此新策略并非最优解,原策略是为最优解。
在代码实现时,按照性价比降序排序,之后依次遍历每一种糖果,在可以装完的情况下就全部装入,否则选取一部分将剩余空间装满即可。在此过程中,依次按照装入比例累加糖果总价值即可。
/*
* Name: T1.cpp
* Problem: 圣诞老人的礼物
* Author: Teacher Gao.
* Date&Time: 2025/01/03 19:27
*/
#include <iostream>
#include <iomanip>
#include <algorithm>
using namespace std;
struct candy {
int v, w;
bool operator<(const candy& a) const {
return v*a.w > a.v*w;
}
} a[105];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int n, w;
cin >> n >> w;
for (int i = 1; i <= n; i++)
cin >> a[i].v >> a[i].w;
sort(a + 1, a + n + 1);
double sum = 0;
for (int i = 1; i <= n; i++) {
if (a[i].w <= w) {
sum += a[i].v;
w -= a[i].w;
}
else {
sum += 1.0 * a[i].v / a[i].w * w;
break;
}
}
cout << fixed << setprecision(1) << sum << endl;
return 0;
}
T2. 数字变换
给定一个包含 5 5 5 个数字( 0 ∼ 9 0\sim 9 0∼9)的字符串,例如 "02943"
,请将 "12345"
变换到它。你可以采取 3 3 3 种操作进行变换
- 交换相邻的两个数字;
- 将一个数字加 1 1 1。如果加 1 1 1 后大于 9 9 9,则变为 0 0 0;
- 将一个数字加倍。如果加倍后大于 9 9 9,则将其变为加倍后的结果除以 10 10 10 的余数。
最多只能用第 2 2 2 种操作 3 3 3 次,第 3 3 3 种操作 2 2 2 次,求最少经过多少次操作可以完成变换。
时间限制:1 s
内存限制:64 MB
- 输入
有最多 1 0 5 10^5 105 组数据,每组数据就是包含 5 5 5 个数字的字符串。 - 输出
对每组数据,输出将"12345"
变换到给定字符串所需要的最少操作步数。如果无法变换成功,输出 − 1 -1 −1。 - 样例输入
12435 99999 12374
- 样例输出
1 -1 3
- 提示
由于测试数据太多,如果对每组数据都从头进行搜索,就会超时。建议先做预处理,即以"12345"
作为初始状态做一遍彻底的广搜,找出"12345"
经合法变换能够到达的所有字符串,并记录到达这些字符串各需要多少步操作。然后对读入的每组数据,在上述预处理记录的结果中进行查询即可。
思路分析
此题考查 B F S \tt BFS BFS,有一定难度。
根据题目的提示信息,我们需要用 B F S \tt BFS BFS 预处理出所有数字串对应的答案。为了便于标记状态,定义