首页 > 其他分享 >Living-Dream 系列笔记 第6期

Living-Dream 系列笔记 第6期

时间:2024-03-09 12:34:04浏览次数:21  
标签:二分 Living return int mid 笔记 pair Dream check

模拟赛。 寄。

T1

对于每次询问,二分查找数组中对应值的原下标即可,因此需要用结构体存储原始数据和原始下标。这当然是比较麻烦的做法。

另一种做法则是开一个 map 替代桶来存储数组中每个元素的下标,对于每个询问输出即可。

另外值得注意的是,本题默认询问之间相互独立

时间复杂度均为 \(O(q \log n)\)。

方法一代码方法二代码

T2

\(Link\)

T3

很多人第一直觉想到对所有任务排序后第一项任务的截止时间 \(-\) 完成时长即为答案。其实不然:

如图,若从第一项任务的截止时间 \(-\) 完成时长的这一时刻开始干,则结束后就不够完成第二项任务了,因此我们需要将时间继续提早。

于是我们就想到了二分答案,原因:

  • 本题是要在能够完成所有任务的情况下找到最迟的开始时间,即在限制条件下找最大值。

  • 同时,本题也具有十分明显的单调性:若从 \(x\) 时刻开始做能做完,则从 \(< x\) 的时刻开始做仍然能做完;若从 \(x\) 时刻开始做不完,则从 \(>x\) 的时刻开始仍然做不完。

证明了可以使用二分答案后,我们考虑如何设计 check 函数:

  • 首先需要对数组按照截止时间排序;

  • 接着模拟一遍完成任务的过程,若超过了当前任务的截止时间则返回 \(0\),否则返回 \(1\)。

#include<bits/stdc++.h>
#define int long long
using namespace std;

int n;
pair<int,int> p[1031];
bool cmp(pair<int,int> &a,pair<int,int> &b){
	return a.second<b.second;
}

bool check(int x){
	int tme=x;
	for(int i=1;i<=n;i++){
		tme+=p[i].first;
		if(tme>p[i].second) return 0;
	}
	return 1;
}

signed main(){
	ios::sync_with_stdio(0);
	cin>>n;
	for(int i=1;i<=n;i++) cin>>p[i].first>>p[i].second;
	sort(p+1,p+n+1,cmp);
	
	int l=-1,r=1e6+1;
	while(l+1<r){
		int mid=(l+r)>>1;
		if(check(mid)) l=mid;
		else r=mid;
	}
	cout<<l;
	return 0;
}

习题

考虑二分 \(R\) 的值。

check 函数中仅需记录一个即将被炸的位置 \(p\) 以及已经投放的奶牛数 \(s\),循环 \(1 \sim n\),若 \(p+mid < a_i\)(即无法炸掉 \(a_i\)),则令 \(s \gets s+1\) 且 \(p=a_i\)。在循环过程中若 \(s>k\),则返回 \(0\),若循环结束后 \(s \le k\),则返回 \(1\)。

注意排序。

#include<bits/stdc++.h>
using namespace std;

int n,k;
int a[50031];

bool check(int x){
    int s=0,p=-1e9;
    for(int i=1;i<=n;i++){
        if(p+x<a[i]){ 
            s++,p=a[i]+x;
            if(s>k) return 0;
        }
    }
    return 1;
}

int main(){
    cin>>n>>k;
    for(int i=1;i<=n;i++) cin>>a[i];
    sort(a+1,a+n+1);
    
    int l=-1,r=1e9+1;
    while(l+1<r){
        int mid=(l+r)>>1;
        if(check(mid)) r=mid;
        else l=mid;
    }
    cout<<r;
    return 0;
}

标签:二分,Living,return,int,mid,笔记,pair,Dream,check
From: https://www.cnblogs.com/XOF-0-0/p/18062524

相关文章

  • Living-Dream 系列笔记 第7期
    本期主要讲解深度优先搜索\(\text{DFS}\)。知识点种类:全排列。可以想象为填格子。去重全排列,即组合。时间复杂度均为\(O(n!)\)。\(\text{DFS}\)题的特征:求方案总数/最值。数据范围极小(一般\(n\le20\))。无法直接暴力枚举(因为循环嵌套层数不确定)。......
  • Living-Dream 系列笔记 第4期
    本期主要讲解二分答案。知识点使用场景:最小值最大化,或最大值最小化。在限制条件下找最值。与二分查找的区别:L、R均为答案,而非下标。输出:最大化输出L,反之输出R。例题T1二分\(M\)的值,边界为\(L=-1,R=\max{\{a_i\}}\)。每次枚举到一个\(mid\)就对于每个......
  • Living-Dream 系列笔记 第5期
    本期主要讲解二分答案的进阶。例题T1二分需要的秒数,在check函数中对于每件衣服,若其在\(x\)秒内无法自然晒干,则使用烘干机,并令\(sum\)加上使用烘干机的秒数,最后判断\(sum\)是否\(\lex\)即可。\(Trick\):二分边界需要按数据范围尽可能开大,不能开小了。#include<bits/......
  • 挑选一款适合自己的笔记本电脑的步骤
    你知道如何挑选一款适合自己的笔记本电脑吗?笔记本电脑有许多品牌和型号,因此挑选出合适的笔记本电脑是一项艰巨的任务。为了能够找到最适合你的笔记本电脑,你需要考虑一系列因素。需要先了解几个常见问题:·从什么渠道购买笔记本·笔记本电脑品牌都有哪些·购买笔记本首先弄清......
  • 3/9 训练笔记
    P5268[SNOI2017]一个简单的询问题解不妨把每个区间表示成\(|V|\)维向量\(b\)的形式,其中\(b[i]\)为在区间\([l,r]\)中,\(i\)出现的次数。然后我们发现要求的实际上是\(a\cdotb\)。拆一下(这里用\(g(i)\)表示\([1,i]\)的向量):\(a\cdotb=[l_1,r_1]\cdot[l_......
  • 课堂笔记2
    define_CRT_SECURE_NO_WARNINGSinclude<stdio.h>//////冒泡排序该方法只能进行整数的排序//voidBubbleSort(intarr[],intsz)//{//inti=0;//intj=0;//for(i=0;i<sz-1;i++)//{//for(j=0;j<sz-1-i;j++)......
  • 王道计算机网络截图笔记
    目录第一章概述1.计算机网络概览1.1网络与计算机网络1.2计算机网络的功能1.3计算机网络的组成1.3.1组成部分1.3.2工作方式1.3.3功能组成1.4计算机网络的分类1.5小结2.计算机网络的标准化工作2.1标准的分类2.2RFC2.3标准化工作的相关组织2.4小结3.计算机网络性能指标3......
  • 2024.3.9 笔记
    2024.3.9笔记P1948题目大意为在无向图上求出从\(1\)到\(N\)的路径,使路径上第\(k+1\)大的边权尽量少。第一种是DP用\(f[i][j]\)表示从\(1\)到点\(i\),用了\(j\)条免费线的最小花费。对于一条\(u->v\)的边\(e\)有转移:不用免费线\(f_{v,k}=min(f_{v,k},max......
  • MYSQl学习笔记19: 外键约束
    外键约束用来让两张表的数据之间建立连接,从而保证数据的一致性和完整性具有外键的表(emp)称为子表外键关联的表(dept)称为父表外键约束创建表时添加createtable表名(字段名数据类型,[constrain][外键名称]foreignkey(外键字段名)references主表(主表......
  • MYSQL学习笔记20: 外键约束(删除/更新行为)
    外键约束删除/更新行为setdefault在mysql的默认引擎innodb中不支持CASCADEaltertable表名addconstraint外键名称foreignkey(外键字段)references主表名(主表字段名)onupdatecascadeondeletecascade;建立外键约束#如果父表和子表建立外键的字段有不同的......