【CF 1018(div.1+2) B】被小学奥数背刺
好了昨天被1018血虐
max好歹还有1348 接连这几场给我干回灰名了
其实灰名也没什么不好是吧(笑)
所以,Div.1+2连B题都做不出来,深夜对着键盘发呆的同学,究竟是谁?
没错,就是我
早上补了B 下面看题目吧:
题目描述
你拥有许多五颜六色的手套,并把它们放在抽屉里。每只手套都有 \(n\) 种颜色,编号为 \(1\) 至 \(n\) 。具体来说,从 \(1\) 到 \(n\) 的每个 \(i\) 中,你有 \(l_i\) 个左手套和 \(r_i\) 个右手套,颜色为 \(i\) 。
不幸的是,现在是深夜,所以您看不到任何手套。换句话说,你只有在从抽屉里拿出手套后,才能知道手套的颜色和类型(左手还是右手)。
一双颜色为 \(i\) 的匹配手套正好由一只左手套和一只颜色为 \(i\) 的右手套组成。求从抽屉中取出的手套的最少数量,以保证至少有 $ k $ 对颜色不同的手套 。
形式上,求最小的正整数 \(x\) ,使得:
- 对于从抽屉中取出的任意一组 \(x\) 手套,总是至少有 \(k\) 对不同颜色的手套。
输入格式
每个测试包含多个测试用例。第一行包含测试用例的数量 \(t\) ( \(1 \le t \le 10^4\) )。测试用例说明如下。
每个测试用例的第一行包含两个整数 \(n\) , \(k\) ( \(1 \leq k \leq n \leq 2 \cdot 10^5\) ) --不同颜色的数量,以及所需的匹配手套对的最小数量。
每个测试用例的第二行包含 \(n\) 个整数 \(l_1, l_2, \ldots, l_n\) ( \(1 \leq l_i \leq 10^9\) ) - 从 \(1\) 到 \(n\) 的每个 \(i\) 中颜色为 \(i\) 的左手套数量。
每个测试用例的第三行包含 \(n\) 个整数 \(r_1, r_2, \ldots, r_n\) ( \(1 \leq r_i \leq 10^9\) ) - 从 \(1\) 到 \(n\) 的每个 \(i\) 中颜色为 \(i\) 的右手套数量。
保证所有测试用例中 \(n\) 的总和不超过 \(2 \cdot 10^5\) 。
输出格式
对于每个测试用例,输出一个整数 - 您需要从抽屉中取出的手套的最少数量。
样例输入
5
3 3
1 1 1
1 1 1
1 1
100
1
3 2
100 1 1
200 1 1
5 2
97 59 50 87 36
95 77 33 13 74
10 6
97 59 50 87 36 95 77 33 13 74
91 14 84 33 54 89 68 34 14 15
样例输出
6
101
303
481
1010
解法&&个人感想
本来我的策略是这样的:
把每种手套的总数量排序,然后取出最大的(k-1)种全部手套,剩下的每个取左右手最大数量,接着加一输出
然后就发现样例最后一个数据过不去,麻了
早上看了答案的策略:
每个都先拿左右手中最大的,剩下的再取最大的前(k-1)个,最后加一
确实有道理 相当于是全局贪心和局部贪心?
思维题一般就是有种顿悟的感觉
下面看代码:
#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define maxn 200005
using namespace std;
int t;
int n,k;
int l[maxn],r[maxn];
int ma[maxn],mi[maxn];
bool cmp(int x,int y){
return x>y;
}
int main(){
scanf("%d",&t);
while(t--){
ll ans=0;
cin>>n>>k;
for(int i=1;i<=n;i++){
cin>>l[i];
}
for(int i=1;i<=n;i++){
cin>>r[i];
ma[i]=max(l[i],r[i]);
mi[i]=min(l[i],r[i]);
}
for(int i=1;i<=n;i++){
ans+=ma[i];
}
sort(mi+1,mi+1+n,cmp);
for(int i=1;i<=k-1;i++){
ans+=mi[i];
}
cout<<ans+1<<endl;
}
system("pause");
return 0;
}
后半学期,也请各位继续关注:
《我的青春线代物语果然有问题》
《高数女主养成计划》
《程设の旅》
《青春猪头少年不会梦到多智能体吃豆人》
《某Linux的开源软件》
还有——
《我的算法竞赛不可能这么可爱》
本期到此结束!

浙公网安备 33010602011771号