当前位置: 首页 > news >正文

计蒜客4月训练赛-普及 T3

前言

为记录调了一上午的代码写的题解QWQ

题目描述

蒜头君给定你一个长度为 n 的整数数组 nums 和一个二维数组 queries,其中 queries[i] = [l_i, r_i, val_i],来进行以下操作:

对于每个 queries[i],表示在数组 nums 上执行以下操作:

  1. 从数组 nums 中选择索引范围在 [l_i, r_i](包含端点,索引从 0 开始)内的一个下标子集
  2. 将所选中的每个下标处对应的数组 nums 中的值减去 val_i。

零数组是指数组中所有元素的值都等于 0 的数组。

数组的子集是指从数组中选择的一些元素(可能为空)。

你需要返回使得按顺序执行前 k 个查询操作后,数组 nums 能够转变为零数组的最小可能的非负整数值 k。如果不存在这样的 k,则返回 -1。 

输入格式

第一行输入一个正整数 n,代表数组 nums 的大小,范围在 1 到 10 之间。

第二行输入 n 个整数,代表数组 nums 每个元素的大小,范围均在 0 到 1000 之间。

第三行输入一个正整数 m,代表二维数组 queries 的长度,范围在 1 到 1000 之间。

接下来 m 行,每行输入三个整数 l_i、r_i、val_i,分别表示 queries 数组中每个子数组的内容,其中 0 <= l_i <= r_i < n,1 <= val_i <= 10。

输出格式

输出使得按顺序执行前 k 个查询操作后,数组 nums 能够转变为零数组的最小可能的非负整数值 k,如果不存在这样的 k,则输出 -1。

样例输入1

3
2 0 2
3
0 2 1
0 2 1
1 1 3

样例输出1

2

样例解释1

  • 初始数组:未明确给出,但可以通过操作推断。
  • 查询0l = 0, r = 2, val = 1,将下标 [0] 和 [2] 的值减1,数组变为 [1, 0, 1]
  • 查询1:再次执行 l = 0, r = 2, val = 1,将下标 [0] 和 [2] 的值减1,数组变为 [0, 0, 0],这是一个零数组。因此,最小的 k 值为 2

样例输入2

4
4 3 2 1
2
1 3 2
0 2 1

样例输出2

-1
  • 解释:即使执行完所有查询,也无法使 nums 变为零数组。

思路

思路很简单,但细节很多。

发现随着k的增加,只要有一个最小的k满足题目要求,那么>=k的数都一定满足要求。

这具备二份的性质。

然后就第一层二分,第二层直接看在这个情况下能否满足题目要求,不能就往大的二分,能就往小的二分。

最后我们需还要做一个变样的DP——每个j求出那几个数可以靠现在可以减的数组合出来(1<=j<=n)。
怎么实现呢?
首先,我们把现在这种情况的前k个枚举一遍,x[i]<=i<=y[i]的都可以使用(1<=i<=k)。
然后就可以使用DP具体实现了(具体见代码)。 

记得DP第二重要反着枚举,不然可能会出现本来x是可以,但你直接把k+2*j也当成可以的了(j为符合要求的某个数值z[i],实际上大概率是不可以的)。

代码

#include <bits/stdc++.h>
using namespace std;
int n,m,k,a[100010],x[100010],y[100010],z[100010],l,r,mid,sum,dp[100010],now=1,ans,fl,mi=1e9;
vector<int>v[100010];
int main(){ios::sync_with_stdio(0);cin>>n;for(int i=1;i<=n;i++){cin>>a[i];//输入}cin>>m;for(int i=1;i<=m;i++){cin>>x[i]>>y[i]>>z[i];x[i]++,y[i]++;//因为从零开始,而我们的是从一开始,要加一!!!(超大坑点)}l=1,r=m;while(l<=r){fl=0;mid=(l+r)/2;for(int i=1;i<=n;i++){v[i].clear();//清空(坑点)}for(int i=1;i<=mid;i++){for(int j=x[i];j<=y[i];j++){v[j].push_back(z[i]);//前mid个操作 }}for(int k=1;k<=n;k++){//每个都要枚举看行不行(小坑)sum=0;//初始化 for(int i=0;i<v[k].size();i++){sum+=v[k][i];//sum为可以减的和}if(sum<a[k]){//不行(全减了都不够)(坑点)fl=1;//标记吧 break;}for(int i=1;i<=sum;i++){dp[i]=0;//初始化(小坑)}dp[0]=1;//dp[i]为可不可以组合出减i,显然0是可以的 for(int j=0;j<v[k].size();j++){for(int i=sum;i>=v[k][j];i--){//反着枚举,不然会出现类似于完全背包的情况if(dp[i-v[k][j]]){dp[i]=1;//变形DP,可以组合出来标记为1}}	}if(!dp[a[k]]){//减不出这个值 fl=1;break;}	}if(!fl){//可以 mi=min(mi,mid);r=mid-1;//不可以实现,尝试更小 }else{l=mid+1;//这都不行,肯定要更大啊 }}if(mi!=1e9){//有方案cout<<mi;//可以有一个k }else{cout<<-1;//不行}return 0;
}

看了那么多,能不能点个赞QWQ  

http://www.xdnf.cn/news/159535.html

相关文章:

  • 运维面试情景题:如果有一块新的硬盘要加入机架如何配置;如果新加了一台服务器,如何配置安全措施
  • 【开源】基于51单片机的简易智能楼道照明设计
  • C语言-函数练习1
  • arcpy列表函数的应用
  • 软件测评中心如何保障软件质量与安全性?
  • autodl(linux)环境下载git-lfs等工具及使用
  • .NET8 依赖注入组件
  • Nacos 集群节点是如何管理的?节点加入和退出的流程是怎样的?
  • 免费送源码:Java+ssm+HTML 三分糖——甜品店网站设计与实现 计算机毕业设计原创定制
  • 2025春季NC:3.1TheTrapeziumRule
  • 哈希表的线性探测C语言实现
  • 嵌入式学习笔记 - HAL_xxx_MspInit(xxx);函数
  • 生成式AI全栈入侵:当GPT-4开始自动编写你的Next.js路由时,人类开发者该如何重新定义存在价值?
  • 梯度下降法
  • MySQL 调优
  • 使用 IntersectionObserver 实现懒加载提升网页性能的高效方案
  • Make + OpenOCD 完成STM32构建+烧录
  • [论文解析]Mip-Splatting: Alias-free 3D Gaussian Splatting
  • 探索 AI 在文化遗产保护中的新使命:数字化修复与传承
  • Unity中文件上传以及下载,获取下载文件大小的解决方案
  • 1--Python基础课程实验指导书
  • Postman脚本处理各种数据的变量
  • 常见的六种大语言模型微调框架
  • Go设计模式-观察者模式
  • html初识
  • 求解,如何控制三相无刷电机?欢迎到访评论
  • 【家政平台开发(81)】让家政服务“绿”起来:平台绿色环保服务推广指南
  • 【Castle-X机器人】五、物联网模块配置与调试
  • 【源码+文档+调试讲解】基于springboot的健身房管理系统
  • 怎样理解ceph?