本题含有B1和B2两个难度版本。由于关系相近,我把他们放在同一篇博客中,可自行选择观看
B1. Bouquet (Easy Version)
time limit per test: 1.5 seconds
memory limit per test: 512 megabytes
input: standard input
output: standard output
This is the easy version of the problem. The only difference is that in this version, the flowers are specified by enumeration.
A girl is preparing for her birthday and wants to buy the most beautiful bouquet. There are a total of \(n\) flowers in the store, each of which is characterized by the number of petals, and a flower with \(k\) petals costs \(k\) coins. The girl has decided that the difference in the number of petals between any two flowers she will use in her bouquet should not exceed one. At the same time, the girl wants to assemble a bouquet with the maximum possible number of petals. Unfortunately, she only has \(m\) coins, and she cannot spend more. What is the maximum total number of petals she can assemble in the bouquet?
这是问题的简单版本。唯一不同的是,在这个版本中,花朵是通过枚举来指定的。
一个女孩准备过生日,她想买一束最漂亮的花。商店里一共有 \(n\) 种花,每种花的特征是花瓣数,有 \(k\) 个花瓣的花需要花费 \(k\) 个硬币。女孩决定,花束中任何两朵花的花瓣数之差都不能超过 1。同时,女孩希望花束的花瓣数尽可能多。不幸的是,她只有 \(m\) 枚金币,无法再花费更多。她能组合的花束的花瓣总数最多是多少?
Input
Each test consists of several test cases. The first line contains a single integer \(t\) (\(1 \le t \le 10\,000\)) — the number of test cases. This is followed by descriptions of the test cases.
The first line of each test case contains two integers \(n\), \(m\) (\(1 \le n \le 2 \cdot 10^5, 1 \le m \le 10^{18}\)) — the number of flowers in the store and the number of coins the girl possesses, respectively. The second line of each test case contains \(n\) integers \(a_1, a_2, \ldots, a_n\) (\(1 \le a_i \le 10^9\)), where \(a_i\) is the number of petals of the \(i\)-th flower in the store.
The sum of \(n\) over all test cases does not exceed \(2 \cdot {10}^5\).
输入
每个测试由多个测试用例组成。第一行包含一个整数 \(t\) ( \(1 \le t \le 10\,000\) ) - 测试用例数。随后是测试用例的说明。
每个测试用例的第一行包含两个整数 \(n\) , \(m\) ( \(1 \le n \le 2 \cdot 10^5, 1 \le m \le 10^{18}\) )--分别是商店里的鲜花数量和女孩拥有的硬币数量。每个测试用例的第二行包含 \(n\) 个整数 \(a_1, a_2, \ldots, a_n\) ( \(1 \le a_i \le 10^9\) ),其中 \(a_i\) 是商店里第 \(i\) 朵花的花瓣数。
所有测试用例的 \(n\) 之和不超过 \(2 \cdot {10}^5\) 。
Output
For each test case, output a single integer — the maximum possible number of petals in the bouquet that the girl can assemble while meeting all the conditions listed above.
输出
对于每个测试用例,输出一个整数,即在满足上述所有条件的情况下,女孩在花束中可能组合的最大花瓣数。
Example
input
5
5 10
1 1 2 2 3
8 20
4 2 7 5 6 1 1 1
8 100000
239 30 610 122 24 40 8 2
11 13
2 4 11 1 1 2 3 5 4 3 2
8 1033
206 206 206 207 207 207 207 1000
output
7
13
610
13
1033
Note
In the first test case, you can assemble a bouquet with \((1, 1, 2, 2), (2, 2, 3), (1, 1), (2, 2)\). The maximum over all valid bouquets not greater than \(10\) is \(7\) for \((2, 2, 3)\). In the third test case, you can assemble a bouquet with only one flower of any type, so the answer is \(610\). In the fourth test case, you can assemble a bouquet with \((4, 4, 5)\), which gives you \(13\) petals, and it is the maximum amount of petals that the girl can buy.
注
在第一个测试用例中,可以用 \((1, 1, 2, 2), (2, 2, 3), (1, 1), (2, 2)\) 组合一个花束。所有不大于 \(10\) 的有效花束的最大值是 \(7\) ,即 \((2, 2, 3)\) 。在第三个测试案例中,你只能用一朵任意类型的花来组合花束,因此答案是 \(610\) 。在第四个测试案例中,你可以用 \((4, 4, 5)\) 组合一束花,这样就可以得到 \(13\) 个花瓣,这也是女孩可以购买的最大花瓣数量。
我的题解
第一题是简单版本,给的数据量比较小
我们可以先排一下序,然后用 双指针算法 模拟 取值
当 后面的指针指向的值
比 前面的值加1
要大,就把前面的指针
不断往后挪
每次更新区间和
每次对区间和做一个判断
- 当区间和大于 \(k\) 时,就把前指针往后挪(减少区间和)
- 否则,就把后指针往后挪(增大区间和)
每次循环都把区间和与答案作比较,取最大值更新答案
循环结束之后输出答案即可
我的代码
#include <bits/stdc++.h>
#define int long long
const int N = 2e5+10;
int t,n,k;
int num;
int a[N];
void solve() {
int ans = 0;
int tem;
std::cin >> n >> k;
for(int i = 0 ; i < n ; i ++) std::cin >> a[i];
std::sort(a,a+n);
int st = 0,en = 0;
tem = a[0];
while(st <= en && en < n) {
while(a[st] +1 < a[en]) {
tem -= a[st];
st ++;
}
if(tem > k) {
tem -= a[st];
st ++;
} else {
ans = std::max(ans,tem);
en ++;
tem += (en < n ? a[en] : 0);
}
}
std::cout << ans << "\n";
}
signed main() {
std::cin >> t;
while(t--) solve();
return 0;
}
B2. Bouquet (Hard Version)
time limit per test: 1.5 seconds
memory limit per test: 256 megabytes
input: standard input
output: standard output
This is the hard version of the problem. The only difference is that in this version, instead of listing the number of petals for each flower, the number of petals and the quantity of flowers in the store is set for all types of flowers.
A girl is preparing for her birthday and wants to buy the most beautiful bouquet. There are a total of \(n\) different types of flowers in the store, each of which is characterized by the number of petals and the quantity of this type of flower. A flower with \(k\) petals costs \(k\) coins. The girl has decided that the difference in the number of petals between any two flowers she will use to decorate her cake should not exceed one. At the same time, the girl wants to assemble a bouquet with the maximum possible number of petals. Unfortunately, she only has \(m\) coins, and she cannot spend more. What is the maximum total number of petals she can assemble in the bouquet?
**这是问题的困难版本。唯一不同的是,在这个版本中,不是列出每种花的花瓣数,而是为所有类型的花设定花瓣数和商店中的花的数量。
一个女孩准备过生日,想买一束最漂亮的花。店里一共有 \(n\) 种不同类型的花,每种花的花瓣数和数量都有相应的特征。一朵有 \(k\) 个花瓣的花的价格是 \(k\) 个金币。女孩决定,她用来装饰蛋糕的任何两朵花的花瓣数之差都不能超过 1。同时,女孩还想用尽可能多的花瓣组合成一束花。不幸的是,她只有 \(m\) 枚金币,无法再花费更多。她能组合的花束花瓣总数最多是多少?
Input
Each test consists of several test cases. The first line contains a single integer \(t\) (\(1 \le t \le 10\,000\)) — the number of test cases. This is followed by descriptions of the test cases.
The first line of each test case contains two integers \(n\), \(m\) (\(1 \le n \le 2 \cdot 10^5, 1 \le m \le 10^{18}\)) — the number of types of flowers in the store and the number of coins the girl possesses, respectively. The second line of each test case contains \(n\) different integers \(a_1, a_2, \ldots, a_n\) (\(1 \le a_i \le 10^9\)), where \(a_i\) is the number of petals of the \(i\)-th flower type in the store (for different indexes \(i \neq j\), it must be \(a_i \neq a_j\)). The third line of each test case contains \(n\) integers \(c_1, c_2, \ldots, c_n\) (\(1 \le c_i \le 10^9\)), where \(c_i\) is the quantity of the \(i\)-th flower type in the store.
The sum of \(n\) over all test cases does not exceed \(2 \cdot {10}^5\).
输入
每个测试由多个测试用例组成。第一行包含一个整数 \(t\) ( \(1 \le t \le 10\,000\) ) - 测试用例数。随后是测试用例的说明。
每个测试用例的第一行包含两个整数 \(n\) , \(m\) ( \(1 \le n \le 2 \cdot 10^5, 1 \le m \le 10^{18}\) ) - 分别是商店中鲜花的种类数和女孩拥有的硬币数。每个测试用例的第二行包含 \(n\) 不同的整数 \(a_1, a_2, \ldots, a_n\) ( \(1 \le a_i \le 10^9\) )。( \(1 \le a_i \le 10^9\) ),其中 \(a_i\) 是商店中 \(i\) /th花朵类型的花瓣数(对于不同的索引 \(i \neq j\) ,必须是 \(a_i \neq a_j\) )。每个测试用例的第三行包含 \(n\) 个整数 \(c_1, c_2, \ldots, c_n\) ( \(1 \le c_i \le 10^9\) ),其中 \(c_i\) 是商店中 \(i\) -th 鲜花类型的数量。
所有测试用例中 \(n\) 的总和不超过 \(2 \cdot {10}^5\) 。
Output
For each test case, print one integer — the maximum possible number of petals in a bouquet that a girl can collect, observing all the conditions listed above.
输出
对于每个测试用例,打印一个整数 - 在遵守上述所有条件的情况下,女孩在花束中可能收集到的最大花瓣数。
Example
input
7
3 10
1 2 3
2 2 1
3 1033
206 207 1000
3 4 1
6 20
4 2 7 5 6 1
1 2 1 3 1 7
8 100000
239 30 610 122 24 40 8 2
12 13123 112 1456 124 100 123 10982
6 13
2 4 11 1 3 5
2 2 1 2 2 1
8 10330
206 210 200 201 198 199 222 1000
9 10 11 12 13 14 15 16
2 10000000000
11 12
87312315 753297050
output
7
1033
19
99990
13
10000
9999999999
Note
In the first test case, some valid bouquets are \((1, 1, 2, 2), (2, 2, 3), (1, 1), (2, 2)\). The maximum over all valid bouquets not greater than \(10\) is \(7\) for \((2, 2, 3)\). In the second test case, you can assemble a valid bouquet with \((206, 206, 207, 207, 207)\) with a sum of \(1033\), which is the maximum number of petals the girl can buy. In the third test case, you can assemble a valid bouquet with \((5, 5, 5, 4)\) with a sum of \(19\). It can be seen that no valid bouquet can have \(20\) petals.
注
在第一个测试用例中,一些有效花束为 \((1, 1, 2, 2), (2, 2, 3), (1, 1), (2, 2)\) 。不大于 \(10\) 的所有有效花束的最大值是 \((2, 2, 3)\) 的 \(7\) 。在第二个测试案例中,可以用 \((206, 206, 207, 207, 207)\) 组合出一个有效花束,花束总数为 \(1033\) ,这是女孩可以购买的最大花瓣数。在第三个测试用例中,可以用 \((5, 5, 5, 4)\) 和 \(19\) 组合出一束有效的花束。由此可见,任何有效花束都不可能有 \(20\) 个花瓣。
我的题解
这题是困难版本
我们可以用计数数组来模拟这个双指针算法的过程以节省内存空间
当然也可以用pair存储,我用的是map存储
我的做法是计数存储之后,
声明一个关于这个map的迭代器,反向遍历
假设迭代器迭代到取花瓣数 \(a\)
每次遍历都只取 \(a\) 和 \(a+1\) 的花瓣数
每次计算,假设迭代器迭代到取花瓣数 \(a\) 和花瓣数 \(b(b = a + 1)\):
先比较 \(a\) 和 \(b\) 总数和 \(k\) 的大小
- 如果小于等于 \(k\),那就全部取
- 如果比 \(k\) 大
- 假设全部取 \(a\) ,会有两种情况
- 全部取 \(a\) 之后手上的花瓣数不超过 \(k\) ,那就再从 \(b\) 那里拿一些花瓣(假设取 \(m\) 朵,使得手上的花瓣数最大且不超过 \(k\) )
- 全部取 \(a\) 之后手上的花瓣数超过 \(k\) ,那就放回部分 \(a\) ,使得手上的花瓣数不大于 \(k\)
- 然后,我们计算最多能把多少朵手上的a换成b(因为每换一朵花瓣数就加 \(1\)),这个数量 $$add = min(剩下的b,手中的a)$$
也就是 $$add = min(b的总数 - m,手中的a)$$ - 再把手上的花瓣数加上 \(add\),和目前的结果比较,取最大值更新结果
- 假设全部取 \(a\) ,会有两种情况
输出最后的结果即可
同样的逻辑套用在B1也可以通过
我的代码
#include <bits/stdc++.h>
#define int long long
const int N = 2e5+10;
int t,n,k;
int num;
int a[N];
int fin(std::map<int,int> &mp,std::map<int,int>::iterator &poi) {
int bi = poi->first+1;
int teme = poi->second * poi->first + mp[bi] * bi;
int ans_t;
if(teme > k) {
ans_t = std::min(k/poi->first,poi->second) * poi->first;
int add_m = std::min((k-ans_t)/bi,mp[bi]);
ans_t += add_m*bi;
int add_t = std::min(std::min(k/poi->first,poi->second),mp[bi]-add_m);
ans_t += std::min(k-ans_t,add_t);
ans_t = std::max(ans_t,std::min(k/bi , mp[bi]) * bi);
return ans_t;
} else {
return teme;
}
}
void solve() {
int ans = 0;
std::cin >> n >> k;
std::map<int,int> mp;
for(int i = 0 ; i < n ; i ++) {
std::cin >> a[i];
}
for(int i = 0 ; i < n ;i ++) {
std::cin >> mp[a[i]];
}
std::map<int,int>::iterator poi = mp.end();
poi --;
while(poi != mp.begin() && ans < k) {
ans = std::max(ans,fin(mp,poi));
poi --;
}
ans = std::max(ans,fin(mp,poi));
std::cout << ans << "\n";
}
signed main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cout.tie(nullptr);
std::cin >> t;
while(t--) solve();
return 0;
}
标签:std,10,le,961,int,题解,Codeforces,花瓣,test
From: https://www.cnblogs.com/jiejiejiang2004/p/18322498