xbh的比赛

news2024/11/23 20:23:13

T1

我们发现第一问很好解决,就直接按照从大到小的顺序排序,然后依次选就行了。
然后第一问的答案就出来了。
随后我们看第二问,我们发现和零一背包很相似。
解决这样一个问题, 我们可以使用 01 背包。用 f i , j , k f_{i, j, k} fi,j,k 表示在前 i 个瓶子中选择了 j 个瓶子, 总容积为 k 的最大不移动的液体体积和。我们可以得到:

f i , j , k = max ⁡ ( f i − 1 , j , k , f i − 1 , j − 1 , k − b i + a i ) f_{i, j, k}=\max \left(f_{i-1, j, k}, f_{i-1, j-1, k-b_{i}}+a_{i}\right) fi,j,k=max(fi1,j,k,fi1,j1,kbi+ai)

然后我们用滚动数组优化,把i这维省去就可以了

#include<bits/stdc++.h>
using namespace std;
#define int long long
int read() {
	int x=0,f=1;
	char ch=getchar();
	while(ch>'9'||ch<'0') {
		if(ch=='-') f=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
	return x*f;
}
const int N=110;
struct node {
	int a,b;
} e[N];
int sum[N];
int all;
bool cmp(node x,node y) {
//	if(x.b==y.b) return x.a>y.a;
	return x.b>y.b;
}
int f[N][10010];
signed main() {
//	freopen("3.in","r",stdin);
	int n=read();
	for(int i=1; i<=n; i++) {
		e[i].a=read();
		all+=e[i].a;
	}
	for(int i=1; i<=n; i++) {
		e[i].b=read();
//		sum[i]=sum[i-1]+e[i].b;
	}
	sort(e+1,e+1+n,cmp);
	int id=0;
	for(int i=1; i<=n; i++) {
		sum[i]=sum[i-1]+e[i].b;
		if(sum[i]>=all) {
			id=i;
			break;
		}
	}
	int res=0,ans=0;
	for(int i=1;i<=id;i++){
		res+=e[i].b;
	}
//	cout<<res<<endl;
	memset(f,-0x3f,sizeof(f));
	f[0][0]=0;
	for(int i=1; i<=n; i++){
		for(int j=id; j; j--){
			for(int k=res; k>=e[i].b; k--){
				f[j][k]=max(f[j][k],f[j-1][k-e[i].b]+e[i].a);
			}
		}
	}
//	cout<<all<<"  "<<res<<endl;
	for(int i=all; i<=res; i++){
//		cout<<f[id][i]<<endl;
		ans=max(ans,f[id][i]);
	} 
//	cout<<"OP"<<sum;
	printf("%lld %lld",id,all-ans);
	return 0;
}

T2

这道题目看到数学式子不能硬求,一般遇到都要进行化简。
我们进行化简: ∑ i = 1 n ( x i − x ˉ ) 2 n = ∑ i = 1 n x i 2 n − ( x ˉ ) 2 \frac{\sum_{i=1}^{n}\left(x_{i}-\bar{x}\right)^{2}}{n}=\frac{\sum_{i=1}^{n} x_{i}^{2}}{n}-(\bar{x})^{2} ni=1n(xixˉ)2=ni=1nxi2(xˉ)2 。显然对于每个询问, 平均数是固定的, 所以题目相当于最小化平方和。假设一开始所有 a i 都取到 l i a_{i} 都取到 l_{i} ai都取到li , 只需要以此为基础将一些 a i a_{i} ai 的值增加。若将 x − 1 x-1 x1 增加到 x x x , 平方和增加 x 2 − ( x − 1 ) 2 = x × 2 − 1 x^{2}-(x-1)^{2}=x \times 2-1 x2(x1)2=x×21 。所以显然每次将最小值增加 1 1 1 最优。
然后我们就是实现了:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll maxn=1e6+26,mx=1e6,mod=998244353;
struct Query {
	ll x,id,ans;
	friend bool operator<(Query xy,Query zb) {
		return xy.x<zb.x;
	}
} qq[maxn];
ll n,q,invn,l[maxn],r[maxn],cnt[maxn],ans,ansx;
ll read() {
	ll x=0,f=1;
	char ch=getchar();
	while(ch>'9'||ch<'0') {
		if(ch=='-') f=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
	return x*f;
}
inline ll Pow(ll x,ll y) {
	if(!y)
		return 1;
	if(y&1)
		return Pow(x,y^1)*x%mod;
	return Pow(x*x%mod,y>>1);
}
int main() {
	n=read(),q=read();
	invn=Pow(n,mod-2);
	for(ll i=1; i<=n; i++) {
		l[i]=read(),r[i]=read();
		ans+=l[i]*l[i];
		ansx+=l[i];
		cnt[l[i]+1]++;
		cnt[r[i]+1]--;
	}
	for(ll i=0; i<=mx; i++)
		cnt[i]+=cnt[i-1];
	for(ll i=1; i<=q; i++) {
		qq[i].x=read();
		qq[i].id=i;
	}
	sort(qq+1,qq+q+1);
	for(ll i=1,j=0; i<=q; i++) {
		while(ansx<qq[i].x) {
			if(qq[i].x-ansx<cnt[j]) {
				cnt[j]-=(qq[i].x-ansx);
				(ans+=(qq[i].x-ansx)*(j*2-1)%mod)%=mod;
				ansx=qq[i].x;
				break;
			}
			ansx+=cnt[j];
			(ans+=cnt[j]*(j*2-1)%mod)%=mod;
			j++;
		}
		qq[i].ans=ans;
		qq[i].x%=mod;
	}
	sort(qq+1,qq+q+1,[](Query xy,Query zb) {return xy.id<zb.id;});
	for(ll i=1; i<=q; i++)
		printf("%lld\n",(qq[i].ans*invn%mod-qq[i].x*qq[i].x%mod*invn%mod*invn%mod+mod)%mod);
	return 0;
}

T3

这道题感觉和滑动窗口很像,然后我们往单调队列想,就不难得出正解。
我们用单调队列来维护给定区间的最大值。
f i , j f_{i,j} fi,j表示,前i个数已经选了j个数的最大值,单调队列里维护的是最大值点的位置,对转移进行优化,省去了不必要的转移

#include<bits/stdc++.h>
using namespace std;
#define int long long
int read() {
	int x=0,f=1;
	char ch=getchar();
	while(ch>'9'||ch<'0') {
		if(ch=='-') f=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
	return x*f;
}

const int N=5050;
int f[N][N];
int q[N];
int a[N];
int ans;
signed main(){
//	freopen("3.in","r",stdin);
	memset(f,0xcf,sizeof f);
	int n=read(),k=read(),x=read();
	for(int i=1;i<=n;i++){
		a[i]=read();
	}
	if(n/k>x){
		puts("-1");
		return 0;
	}
	f[0][0]=0;
	for(int j=1;j<=x;j++){
		int l=1,r=1;
		q[r]=0;
		for(int i=1;i<=n;i++){
			while(l<=r&&q[l]+k<i) l++;
			f[i][j]=f[q[l]][j-1]+a[i];
			while(l<=r&&f[i][j-1]>=f[q[r]][j-1]) r--;
			q[++r]=i;
		}
	}
	for(int i=n-k+1;i<=n;i++){
		ans=max(ans,f[i][x]);
	}
	printf("%lld",ans);
	return 0;
}

T4

说来也奇怪,我的贪心跑出来的最小值比答案的最小值还小,得分 17 p t s 17pts 17pts
先说一下我的假做法。
我们可以按高度进行排序,然后我们就依次进行判断就行了,这样肯定是假的,但是在写不出正解的情况下就得写一个这个。

#include<bits/stdc++.h>
using namespace std;
#define int long long
int read(){
	int x=0,f=1;char ch=getchar();
	while(ch>'9'||ch<'0'){
		if(ch=='-') f=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
	return x*f;
}
const int N=1e5+10;
struct node{
	int h,w; 
}gf[N];//女朋友 
bool cmp(node a,node b){
	return a.h>b.h;
}
signed main(){
//	freopen("1.in","r",stdin);
	int n=read(),l=read();
	for(int i=1;i<=n;i++){
		gf[i].h=read(),gf[i].w=read();
	}
	sort(gf+1,gf+1+n,cmp);
	int ans=0,res=0;
	int maxn=0;
	for(int i=1;i<=n;i++){
		if(res+gf[i].w>l){
			res=0;
//			cout<<maxn<<endl;
			ans+=maxn;
			maxn=0;
		}
		res+=gf[i].w;
		maxn=max(maxn,gf[i].h);
	}
	ans+=maxn;
	printf("%lld",ans);
	return 0;
}

然后考虑正解
用线段树优化DP
f i f_{i} fi 表示第 i i i 本书结尾时高度和的最小值。

f i = min ⁡ ( f j + max ⁡ ( h j + 1 , … , h i ) ) ( w j + 1 + … + w i ≤ L ) f_{i}=\min \left(f_{j}+\max \left(h_{j+1}, \ldots, h_{i}\right)\right)\left(w_{j+1}+\ldots+w_{i} \leq L\right) fi=min(fj+max(hj+1,,hi))(wj+1++wiL)

w w w 这个限制我们可以通过二分得到
现在我们把问题转化成:

f i = min ⁡ ( f j + max ⁡ ( h j + 1 , … , h i ) ) ( pos ⁡ i ≤ j ) f_{i}=\min \left(f_{j}+\max \left(h_{j+1}, \ldots, h_{i}\right)\right)\left(\operatorname{pos}_{i} \leq j\right) fi=min(fj+max(hj+1,,hi))(posij)

其中 p o s i p o s_{i} posi 为第 i 个位置的最左端点。

然后是如何使用线段树优化
p o s i pos_i posi的值我们可以在一开始用双指针把区间存起来
而且我们还能用线段树二分来找到 p o s i pos_i posi 这个值,但设个我感觉就复杂了
首先, 我们先开一个单调栈, 对于每个位置找出第一个大于 h i h_{i} hi 的位置 l , 并将 [ l + 1 , i ] [l+1, i] [l+1,i] 这段区间内的 h h h 赋为 h i h_{i} hi 。单调栈可以直接找到需要更新区间的端点

我们发现每一个位置的 f f f 是确定的, 我们每次只需区间修改 h h h 的值, 然后维护 f + h f+h f+h f f f 的最小值。
最后更新用区间查询就行了

#include <bits/stdc++.h>
#define ll long long
#define lson (rt<<1)
#define rson (rt<<1|1)
using namespace std;
const int maxn=100000+10;
const ll inf=1e18;
int n,L,w[maxn],h[maxn],pre[maxn],sta[maxn],top;
ll sum[maxn],f[maxn],Min[maxn<<2],val[maxn<<2],tag[maxn<<2];
// Min 为 f + h 的最小值
// val 为 f 的最小值

inline int read() {
	register int x=0,f=1;
	char ch=getchar();
	while(!isdigit(ch)) {
		if(ch=='-')f=-1;
		ch=getchar();
	}
	while(isdigit(ch)) {
		x=(x<<3)+(x<<1)+ch-'0';
		ch=getchar();
	}
	return (f==1)?x:-x;
}

inline void pushup(int rt) {
	Min[rt]=min(Min[lson],Min[rson]);
	val[rt]=min(val[lson],val[rson]);
}

inline void pushdown(int rt) {
	if(tag[rt]!=inf) {
		Min[lson]=val[lson]+tag[rt];
		Min[rson]=val[rson]+tag[rt];
		tag[lson]=tag[rson]=tag[rt];
		tag[rt]=inf;
	}
}

void build(int l,int r,int rt) {
	Min[rt]=val[rt]=tag[rt]=inf;
	if(l == r) return ;
	int mid=(l+r)>>1;
	build(l,mid,lson);
	build(mid+1,r,rson);
}

void update(int L,int R,int C,int l,int r,int rt) {
	if(L <= l && r <= R) {
		Min[rt]=val[rt]+C;
		tag[rt]=C;
		return ;
	}
	pushdown(rt);
	int mid=(l+r)>>1;
	if(L <= mid) update(L,R,C,l,mid,lson);
	if(R > mid) update(L,R,C,mid+1,r,rson);
	pushup(rt);
}

void modify(int x,int l,int r,int rt) {
	if(l == r) {
		Min[rt]=inf;
		val[rt]=f[l-1];
		return ;
	}
	pushdown(rt);
	int mid=(l+r)>>1;
	if(x <= mid) modify(x,l,mid,lson);
	else modify(x,mid+1,r,rson);
	pushup(rt);
}

ll query(int L,int R,int l,int r,int rt) {
	if(L <= l && r <= R) return Min[rt];
	pushdown(rt);
	int mid=(l+r)>>1;
	ll ans=inf;
	if(L <= mid) ans=min(ans,query(L,R,l,mid,lson));
	if(R > mid) ans=min(ans,query(L,R,mid+1,r,rson));
	return ans;
}

int main() {
	n=read(),L=read();
	for(int i=1; i<=n; i++) {
		h[i]=read(),w[i]=read();
		sum[i]=sum[i-1]+w[i];
	}
	sta[++top]=1;
	for(int i=2; i<=n; i++) {
		while(top&&h[i]>h[sta[top]]) top--;
		if(top) pre[i]=sta[top];
		sta[++top]=i;
	}
	build(1,n,1);
	for(int i=1; i<=n; i++) {
		modify(i,1,n,1);
		if(pre[i]+1<=i) update(pre[i]+1,i,h[i],1,n,1);
		int l=lower_bound(sum,sum+i+1,sum[i]-L)-sum;
		if(l<i) f[i]=query(l+1,i,1,n,1);
	}
	printf("%lld\n",f[n]);
	return 0;
}

这次比赛全是DP,差评完全不像模拟赛

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2246226.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

39页PDF | 毕马威_数据资产运营白皮书(限免下载)

一、前言 《毕马威数据资产运营白皮书》探讨了数据作为新型生产要素在企业数智化转型中的重要性&#xff0c;提出了数据资产运营的“三要素”&#xff08;组织与意识、流程与规范、平台与工具&#xff09;和“四重奏”&#xff08;数据资产盘点、评估、治理、共享&#xff09;…

数据科学与SQL:组距分组分析 | 区间分布问题

目录 0 问题描述 1 数据准备 2 问题分析 3 小结 0 问题描述 绝对值分布分析也可以理解为组距分组分析。对于某个指标而言&#xff0c;一个记录对应的指标值的绝对值&#xff0c;肯定落在所有指标值的绝对值的最小值和最大值构成的区间内&#xff0c;根据一定的算法&#x…

使用 PyTorch-BigGraph 构建和部署大规模图嵌入的完整教程

当涉及到图数据时&#xff0c;复杂性是不可避免的。无论是社交网络中的庞大互联关系、像 Freebase 这样的知识图谱&#xff0c;还是推荐引擎中海量的数据量&#xff0c;处理如此规模的图数据都充满挑战。 尤其是当目标是生成能够准确捕捉这些关系本质的嵌入表示时&#xff0c;…

23种设计模式-模板方法(Template Method)设计模式

文章目录 一.什么是模板方法模式&#xff1f;二.模板方法模式的特点三.模板方法模式的结构四.模板方法模式的应用场景五.模板方法模式的优缺点六.模板方法模式的C实现七.模板方法模式的JAVA实现八.代码解析九.总结 类图&#xff1a; 模板方法设计模式类图 一.什么是模板方法模…

.net的winfrom程序 窗体透明打开窗体时出现在屏幕右上角

窗体透明&#xff0c; 将Form的属性Opacity&#xff0c;由默认的100% 调整到 80%(尽量别低于50%)&#xff0c;这个数字越小越透明&#xff01; 打开窗体时出现在屏幕右上角 //构造函数 public frmCalendarList() {InitializeComponent();//打开窗体&#xff0c;窗体出现在屏幕…

DRNN 神经网络的Jacobian 信息辨识

DRNN 神经网络的 Jacobian 信息辨识 1. 基本原理 Jacobian 矩阵用于描述多输入多输出系统中输入和输出之间的偏导关系&#xff0c;其形式为&#xff1a; 对于 DRNN&#xff08;Dynamic Recurrent Neural Network&#xff09;&#xff0c;其动态特性使得 y(t)\mathbf{y}(t)y(t…

iptables网络安全服务详细使用

iptables防火墙概念说明 开源的基于数据包过滤的网络安全策略控制工具。 centos6.9 --- 默认防火墙工具软件iptables centos7 --- 默认防火墙工具软件firewalld&#xff08;zone&#xff09; iptables主要工作在OSI七层的二、三、四层&#xff0c;如果重新编译内核&…

《DAMA 数据管理知识体系指南》读书笔记 - 第 2 章 数据处理伦理

文章目录 1. 章节概述2. 核心概念与定义3. 重要方法与实践步骤4. 理论与实际结合5. 重点6. 理解与记忆要点7. 复习思考题标题图——书籍图片 WPS AI生成的XMind链接&#xff08;不用要源文件&#xff0c;下载不了&#xff09;&#xff1a; 【金山文档 | WPS云文档】 第2章 数据…

《线性代数的本质》

之前收藏的一门课&#xff0c;刚好期末复习&#xff0c;顺便看一看哈哈 课程链接&#xff1a;【线性代数的本质】合集-转载于3Blue1Brown官方双语】 向量究竟是什么 线性代数中最基础、最根源的组成部分就是向量&#xff0c;需要先明白什么是向量 不同专业对向量的看法 物理专…

AI 大模型如何重塑软件开发流程?——技术革新与未来展望

人工智能的蓬勃发展为许多领域注入了强劲动力&#xff0c;而在软件开发这一关键技术领域&#xff0c;AI 大模型的应用正在彻底改变传统流程。从代码自动生成到智能测试&#xff0c;再到协同开发和流程优化&#xff0c;AI 正逐步成为软件开发者的得力助手&#xff0c;也推动企业…

三季度业绩亮点多元,宝尊全域经营走向破茧成蝶

电商行业的变革从未停止&#xff0c;始终反映着网络消费和品牌发展的趋势&#xff0c;以及未来的想象空间&#xff0c;因此令赛道上的相关公司备受关注。 那么&#xff0c;当前赛道正在发生哪些变化&#xff1f;11月21日&#xff0c;行业龙头宝尊电商发布截至2024年9月30日的2…

机器学习day7-线性回归3、逻辑回归、聚类、SVC

7欠拟合与过拟合 1.欠拟合 模型在训练数据上表现不佳&#xff0c;在新的数据上也表现不佳&#xff0c;常发生在模型过于简单无法处理数据中的复杂模式时。 特征&#xff1a; 训练误差较高 测试误差也高 模型过于简化&#xff0c;不能充分学习训练数据中的模式 2.过拟合 …

【云计算】腾讯云架构高级工程师认证TCP--考纲例题,知识点总结

【云计算】腾讯云架构高级工程师认证TCCP–知识点总结&#xff0c;排版整理 文章目录 1、云计算架构概论1.1 五大版块知识点&#xff08;架构设计&#xff0c;基础服务&#xff0c;高阶技术&#xff0c;安全&#xff0c;上云&#xff09;1.2 课程详细目录1.3 云基础架构设计1.4…

proto3语法详解

proto3语法详解 字段规则消息类型的定义与使⽤定义使用 enum类型定义与使用定义规则定义时注意事项 Any类型Any类型介绍Any类型使用 oneof类型oneof类型的介绍oneof类型的使用 map类型map类型的介绍map类型的使用 默认值更新消息更新规则保留字段reserved 未知字段未知字段获取…

【STM32】在 STM32 USB 设备库添加新的设备类

说实话&#xff0c;我非常想吐槽 STM32 的 USB device library&#xff0c;总感觉很混乱。 USB Device library architecture 根据架构图&#xff1a; Adding a custom class 如果你想添加新的设备类&#xff0c;必须修改的文件有 usbd_desc.cusbd_conf.cusb_device.c 需要…

怎么编译OpenWrt镜像?-基于Widora开发板

1.准备相应的环境&#xff0c;我使用的环境是VMware16ubuntu20.04&#xff0c;如图1所示安装编译所需的依赖包&#xff1b; sudo apt-get install build-essential asciidoc binutils bzip2 gawk gettext git libncurses5-dev libz-dev patch python3 python2.7 unzip zlib1g-…

神经网络问题之一:梯度消失(Vanishing Gradient)

梯度消失&#xff08;Vanishing Gradient&#xff09;问题是深度神经网络训练中的一个关键问题&#xff0c;它主要发生在反向传播过程中&#xff0c;导致靠近输入层的权重更新变得非常缓慢甚至几乎停滞&#xff0c;严重影响网络的训练效果和性能。 图1 在深度神经网络中容易出现…

JavaWeb之综合案例

前言 这一节讲一个案例 1. 环境搭建 然后就是把这些数据全部用到sql语句中执行 2.查询所有-后台&前台 我们先写后台代码 2.1 后台 2.2 Dao BrandMapper&#xff1a; 注意因为数据库里面的名称是下划线分割的&#xff0c;我们类里面是驼峰的&#xff0c;所以要映射 …

PLC与PLC跨网段通讯的几种方法:厂区组网实践

PLC通常通过以太网或其他工业网络协议&#xff08;如PROFINET、Modbus TCP等&#xff09;进行通信。当PLC位于不同的网段时&#xff0c;它们不能直接通信&#xff0c;需要特殊的配置或设备来实现通信&#xff0c;不同网段的PLC通讯变得尤为重要。 随着工业网络的发展和工业4.0概…

原生openGauss与Oracle数据库函数兼容性对比验证测试

———————————————— 一、测试目的 近期在进行调研去O,为此研究了下原生openGauss和Oracle数据库兼容性&#xff0c;特整理测试了Oracle常用函数和openGauss数据库的对比测试。 二、创建DUAL虚拟表 openGauss 数据库不提供DUAL虚拟表&#xff0c;需要通过如下方…