CF1945题解

CF1945A

贪心简单题
先把b自己内部组合,再考虑与c组合

CF1945B

简单题数学题

因为在0m的时间内一定能覆盖所有的情况,所以对0m的时间内最多烟花数进行小学2年纪计算即可

CF1945C

简单题

枚举每一个断点,记录答案即可

CF1945D

挺好玩的一道贪心题。

转化一下式子,我们发现 a[i],b[i] 的选择过程类似于一个上下反复横跳的最终的选取停止在 a 数组的一个过程,如下图。

注意到对于一个 j 位置,我们只会在 a[j]b[j] 中选一个对答案产生贡献,且在 m+1,m+2,,n 之间选哪一个数并不会对之后的决策产生影响(无后效性)。

因为在 m+1,m+2,,n 之间我们每个选择是独立的,所以在 m+1,m+2,,n 之间直接贪心,对答案的贡献即为 i=m+1nmin{a[i],b[i]}

那么在 1,2,,m 这一段对答案的贡献就显而易见了,因为在这一段中只要选择了 a[j] 就停止选择了,所以答案的组成既是一段 bj+1,bj+2,,bm 再加上 aj

所以只需要统计一下 mini=1m{j=i+1mb[j]+a[i]} 即可

最终答案即是这两段贡献的加和

代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+5,inf=1e18+5;
int n,m,t;
int a[N],b[N];
signed main(){
	scanf("%lld",&t);
	while(t--){
		scanf("%lld%lld",&n,&m);
		for(int i=1;i<=n;i++){
			scanf("%lld",&a[i]);
		}
		for(int i=1;i<=n;i++){
			scanf("%lld",&b[i]);
		}
		int cnt=0,ans=inf;
		for(int i=n;i>=1;i--){
			if(i>m){
				if(a[i]>b[i]){
					cnt+=b[i];
				}
				else{
					cnt+=a[i];
				}
			}
			else{
				ans=min(ans,cnt+a[i]);
				cnt+=b[i];
			}
		}
		printf("%lld\n",ans);
	}
}

CF1945E

非常好玩的一道题,使我的脑子旋转

首先我先从x有序和二进制这两方面考虑,然后发现这是大大的没前途的

于是我有前途的打开了题解

首先我们考虑先进行一遍二分得出的答案为 a[l],然后考虑一条性质如果我们在二分的时候没有访问到x这个元素,那么我们直接将 l,x 交换是合法的

所以我们由这条性质进行一个分讨:

若二分时没有访问到这个元素直接一步交换

若访问到了则在进行一个分讨:

p[l]<x 则考虑将 l,x 交换,二分时在x这一位上因为 m<=x 所以 l=m,而交换后因为 p[l]<x 所以 l 依旧等于 m,所以对于这种情况,还是交换l,x

p[l]>x 我们考虑只要 a[m]<=xl 就会等于 m 所以说,因为 a[m]<=x ,所以 l 必然是没有被更新过的,所以二分过程中也没有访问到x,所以直接交换就完了

综上所述,我们就跑一遍二分然后交换 a[l],x 即可,注意特判 a[l]==x直接输出0即可

posted @   daydreamer_zcxnb  阅读(41)  评论(1编辑  收藏  举报
相关博文:
阅读排行:
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
点击右上角即可分享
微信分享提示