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

洛谷9.16

[HNOI2004] 打鼹鼠

题目描述

鼹鼠是一种很喜欢挖洞的动物,但每过一定的时间,它还是喜欢把头探出到地面上来透透气的。根据这个特点阿牛编写了一个打鼹鼠的游戏:在一个 n × n n \times n n×n 的网格中,在某些时刻鼹鼠会在某一个网格探出头来透透气。你可以控制一个机器人来打鼹鼠,如果 i i i 时刻鼹鼠在某个网格中出现,而机器人也处于同一网格的话,那么这个鼹鼠就会被机器人打死。而机器人每一时刻只能够移动一格或停留在原地不动。机器人的移动是指从当前所处的网格移向相邻的网格,即从坐标为 ( i , j ) (i, j) (i,j) 的网格移向 ( i − 1 , j ) , ( i + 1 , j ) , ( i , j − 1 ) , ( i , j + 1 ) (i-1, j), (i+1, j), (i, j-1), (i, j+1) (i1,j),(i+1,j),(i,j1),(i,j+1) 四个网格,机器人不能走出整个 n × n n \times n n×n 的网格。游戏开始时,你可以自由选定机器人的初始位置。

现在知道在一段时间内,鼹鼠出现的时间和地点,请编写一个程序使机器人在这一段时间内打死尽可能多的鼹鼠。

输入格式

第一行为 n , m n, m n,m n ≤ 1000 n \le 1000 n1000 m ≤ 10 4 m \le {10}^4 m104),其中 m m m 表示在这一段时间内出现的鼹鼠的个数,接下来的 m m m 行中每行有三个数据 t i m e , x , y \mathit{time}, x, y time,x,y 表示在游戏开始后 t i m e \mathit{time} time 个时刻,在第 x x x 行第 y y y 个网格里出现了一只鼹鼠。 t i m e \mathit{time} time 按递增的顺序给出。注意同一时刻可能出现多只鼹鼠,但同一时刻同一地点只可能出现一只鼹鼠。

输出格式

仅包含一个正整数,表示被打死鼹鼠的最大数目。

样例 #1

样例输入 #1

2 2	         
1 1 1		
2 2 2

样例输出 #1

1

思路

d p [ i ] dp[i] dp[i]为地鼠序列中以下标为 i i i结尾的已打地鼠的数量,遍历其他的地鼠 j j j,若曼哈顿距离小于 t i − t j t_i-t_j titj,则说明能打到下一个地鼠,状态转移

  • i f t j − t i > d i s ( i , j ) t h e n d p [ i ] = m a x ( d p [ i ] , d p [ j ] + 1 ) if \ t_j-t_i>dis(i,j) \ then \ dp[i]=max(dp[i],dp[j]+1) if tjti>dis(i,j) then dp[i]=max(dp[i],dp[j]+1)
    为了防止重复遍历,令 j j j的下标小于 i i i

代码

#include<bits/stdc++.h>
using namespace std;
const int M = 10005;
int n, m;
struct node_ {int t, x, y;
}node[M];
int dp[M];
bool check(node_ a, node_ b) {int dis = abs(a.x - b.x) + abs(a.y - b.y);return dis <= b.t - a.t;
}
int main() {cin.tie(0);cout.tie(0);ios::sync_with_stdio(0);cin >> n >> m;for(int i = 1; i <= m; i ++ ) {cin >> node[i].t >> node[i].x >> node[i].y;dp[i] = 1;}for(int i = 1; i <= m; i ++ ) {for(int j = 1; j < i; j ++ ) {if(check(node[j], node[i])) dp[i] = max(dp[i], dp[j] + 1);}}int res = 1;for(int i = 1; i <= m; i ++ ) {res = max(res, dp[i]);}cout << res << endl;return 0;
}

[NOIP1999 提高组] 导弹拦截

题目描述

某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。某天,雷达捕捉到敌国的导弹来袭。由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。

输入导弹依次飞来的高度,计算这套系统最多能拦截多少导弹,如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。

输入格式

一行,若干个整数,中间由空格隔开。

输出格式

两行,每行一个整数,第一个数字表示这套系统最多能拦截多少导弹,第二个数字表示如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。

样例 #1

样例输入 #1

389 207 155 300 299 170 158 65

样例输出 #1

6
2

提示

对于前 50 % 50\% 50% 数据(NOIP 原题数据),满足导弹的个数不超过 1 0 4 10^4 104 个。该部分数据总分共 100 100 100 分。可使用 O ( n 2 ) \mathcal O(n^2) O(n2) 做法通过。
对于后 50 % 50\% 50% 的数据,满足导弹的个数不超过 1 0 5 10^5 105 个。该部分数据总分也为 100 100 100 分。请使用 O ( n log ⁡ n ) \mathcal O(n\log n) O(nlogn) 做法通过。

对于全部数据,满足导弹的高度为正整数,且不超过 5 × 1 0 4 5\times 10^4 5×104

此外本题开启 spj,每点两问,按问给分。

NOIP1999 提高组 第一题


upd 2022.8.24 \text{upd 2022.8.24} upd 2022.8.24:新增加一组 Hack 数据。

思路

求最多能拦截多少枚实际是求最长不上升子序列,求需要多少导弹系统实际是求最长上升子序列

  • 对于 i < j , d p [ j ] = d p [ i ] + 1 , a [ i ] > = a [ j ] i<j,dp[j]=dp[i]+1,a[i]>=a[j] i<j,dp[j]=dp[i]+1,a[i]>=a[j],这是最长上升子序列的状态转移,最朴素的做法使用两重循环,此时复杂度为 O ( n 2 ) O(n^2) O(n2),求最长上升子序列与这个类似,这样做只能过一半的数据,因此考虑优化
  • 使用down[i]维护不上升子序列的状态,若 a [ i ] < = d o w n . b a c k ( ) a[i]<=down.back() a[i]<=down.back(),则将 a [ i ] a[i] a[i]加入到 d o w n down down中,否则找到第一个小于 a [ i ] a[i] a[i]的元素进行替换,为什么是小于不是小于等于呢,例如若 a [ i ] = 3 d o w n = [ 5 , 3 , 2 ] a[i]=3 \ down = [5, 3 ,2] a[i]=3 down=[5,3,2]那么接下来 d o w n down down应该变成 [ 5 , 3 , 3 ] [5, 3, 3] [5,3,3]而不是 [ 5 , 3 , 2 ] [5,3,2] [5,3,2],同理可以使用一个 u p [ i ] up[i] up[i]维护上升子序列的状态,完成最长上升子序列

代码

#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
int n, h[N];
int up[N], down[N];
int ttup = -1, ttdown = -1;int find1(int l, int r, int x) { // 降序,找第一个小于x元素,若x=3 down = 5 3 2 则应该变成 5 3 3 而不是 5 3 2 所以是找第一个小于xwhile(l < r) {int mid = (l + r) >> 1;if(down[mid] < x) r = mid;else l = mid + 1;}return l;
}
int find2(int l, int r, int x) { // 升序,找第一个大于等于x的元素  x = 4 up = 3 5 7 变成 3 4 7while(l < r) {int mid = (l + r) >> 1;if(up[mid] >= x) r = mid;else l = mid + 1;}return l;
}
void print() {cout << "up == ";for(int i = 0; i <= ttup; i ++ ) {cout << up[i] << " ";}cout << endl;cout << "down == ";for(int i = 0; i <= ttdown; i ++ ) {cout << down[i] << " ";}cout << endl;
}
int main() {cin.tie(0);cout.tie(0);ios::sync_with_stdio(0);while(cin >> h[n]) n ++ ;for(int i = 0; i < n; i ++ ) {if(ttdown == -1 || down[ttdown] >= h[i]) down[++ ttdown] = h[i];else {int pos = find1(0, ttdown, h[i]);down[pos] = h[i];}if(ttup == -1 || up[ttup] < h[i]) up[++ ttup] = h[i];else {int pos = find2(0, ttup, h[i]);up[pos] = h[i];}
//        print();}cout << ttdown + 1 << endl << ttup + 1 << endl;return 0;
}

kkksc03考前临时抱佛脚

题目背景

kkksc03 的大学生活非常的颓废,平时根本不学习。但是,临近期末考试,他必须要开始抱佛脚,以求不挂科。

题目描述

这次期末考试,kkksc03 需要考 4 4 4 科。因此要开始刷习题集,每科都有一个习题集,分别有 s 1 , s 2 , s 3 , s 4 s_1,s_2,s_3,s_4 s1,s2,s3,s4 道题目,完成每道题目需要一些时间,可能不等( A 1 , A 2 , … , A s 1 A_1,A_2,\ldots,A_{s_1} A1,A2,,As1 B 1 , B 2 , … , B s 2 B_1,B_2,\ldots,B_{s_2} B1,B2,,Bs2 C 1 , C 2 , … , C s 3 C_1,C_2,\ldots,C_{s_3} C1,C2,,Cs3 D 1 , D 2 , … , D s 4 D_1,D_2,\ldots,D_{s_4} D1,D2,,Ds4)。

kkksc03 有一个能力,他的左右两个大脑可以同时计算 2 2 2 道不同的题目,但是仅限于同一科。因此,kkksc03 必须一科一科的复习。

由于 kkksc03 还急着去处理洛谷的 bug,因此他希望尽快把事情做完,所以他希望知道能够完成复习的最短时间。

输入格式

本题包含 5 5 5 行数据:第 1 1 1 行,为四个正整数 s 1 , s 2 , s 3 , s 4 s_1,s_2,s_3,s_4 s1,s2,s3,s4

2 2 2 行,为 A 1 , A 2 , … , A s 1 A_1,A_2,\ldots,A_{s_1} A1,A2,,As1 s 1 s_1 s1 个数,表示第一科习题集每道题目所消耗的时间。

3 3 3 行,为 B 1 , B 2 , … , B s 2 B_1,B_2,\ldots,B_{s_2} B1,B2,,Bs2 s 2 s_2 s2 个数。

4 4 4 行,为 C 1 , C 2 , … , C s 3 C_1,C_2,\ldots,C_{s_3} C1,C2,,Cs3 s 3 s_3 s3 个数。

5 5 5 行,为 D 1 , D 2 , … , D s 4 D_1,D_2,\ldots,D_{s_4} D1,D2,,Ds4 s 4 s_4 s4 个数,意思均同上。

输出格式

输出一行,为复习完毕最短时间。

样例 #1

样例输入 #1

1 2 1 3		
5
4 3
6
2 4 3

样例输出 #1

20

提示

1 ≤ s 1 , s 2 , s 3 , s 4 ≤ 20 1\leq s_1,s_2,s_3,s_4\leq 20 1s1,s2,s3,s420

1 ≤ A 1 , A 2 , … , A s 1 , B 1 , B 2 , … , B s 2 , C 1 , C 2 , … , C s 3 , D 1 , D 2 , … , D s 4 ≤ 60 1\leq A_1,A_2,\ldots,A_{s_1},B_1,B_2,\ldots,B_{s_2},C_1,C_2,\ldots,C_{s_3},D_1,D_2,\ldots,D_{s_4}\leq60 1A1,A2,,As1,B1,B2,,Bs2,C1,C2,,Cs3,D1,D2,,Ds460

思路

贪心,由于只能同时完成同一科的两门课,因此对每一科单独分析,使每一科完成时间最短,最后相加即可,单科完成时间可以使用背包来做

代码

#include<bits/stdc++.h>
using namespace std;
int s[5][25];
int d[5];
int dp[5][2000];
int main() {for(int i = 1; i <= 4; i ++ ) cin >> s[i][0];for(int i = 1; i <= 4; i ++ ) {for(int j = 1; j <= s[i][0]; j ++ ) {cin >> s[i][j];d[i] += s[i][j];}}for(int i = 1; i <= 4; i ++ ) {for(int j = 1; j <= s[i][0]; j ++ ) {for(int k = d[i] / 2; k >= s[i][j]; k -- ) {dp[i][k] = max(dp[i][k], dp[i][k - s[i][j]] + s[i][j]);}}}int res = 0;for(int i = 1; i <= 4; i ++ ) {res += d[i] - dp[i][d[i]/2];}cout << res << endl;return 0;
}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 【C++】入门基础(下)
  • Java 流 (Stream) 详解
  • 电气自动化入门01:电工基础
  • 整型提升整型提升练习题
  • 用于稀疏自适应深度细化的掩码空间传播网络 CVPR2024
  • 前端基础知识+算法(一)
  • Java 入门指南:JVM(Java虚拟机)垃圾回收机制 —— 死亡对象判断方法
  • pytorch快速入门(一)—— 基本工具及平台介绍
  • WebGL系列教程八(GLSL着色器基础语法)
  • 采用qt做一个命令行终端
  • 面向对象程序设计之继承(C++)
  • ai 回答HFS是什么 HTTP的文件服务器是什么
  • Leetcode3282. 到达数组末尾的最大得分
  • new/delete和malloc/free到底有什么区别
  • VUE + NODE 历史版本安装
  • 【mysql】环境安装、服务启动、密码设置
  • 【技术性】Search知识
  • 2017 前端面试准备 - 收藏集 - 掘金
  • Debian下无root权限使用Python访问Oracle
  • GDB 调试 Mysql 实战(三)优先队列排序算法中的行记录长度统计是怎么来的(上)...
  • hadoop入门学习教程--DKHadoop完整安装步骤
  • JS创建对象模式及其对象原型链探究(一):Object模式
  • JS基础篇--通过JS生成由字母与数字组合的随机字符串
  • python学习笔记-类对象的信息
  • SOFAMosn配置模型
  • spring boot下thymeleaf全局静态变量配置
  • 复杂数据处理
  • 配置 PM2 实现代码自动发布
  • 前端面试总结(at, md)
  • 入职第二天:使用koa搭建node server是种怎样的体验
  • 少走弯路,给Java 1~5 年程序员的建议
  • 无服务器化是企业 IT 架构的未来吗?
  • 线上 python http server profile 实践
  • 中国人寿如何基于容器搭建金融PaaS云平台
  • Mac 上flink的安装与启动
  • 湖北分布式智能数据采集方法有哪些?
  • #QT(TCP网络编程-服务端)
  • #进阶:轻量级ORM框架Dapper的使用教程与原理详解
  • #我与Java虚拟机的故事#连载04:一本让自己没面子的书
  • #我与Java虚拟机的故事#连载07:我放弃了对JVM的进一步学习
  • ( 10 )MySQL中的外键
  • (02)Cartographer源码无死角解析-(03) 新数据运行与地图保存、加载地图启动仅定位模式
  • (2015)JS ES6 必知的十个 特性
  • (42)STM32——LCD显示屏实验笔记
  • (6)【Python/机器学习/深度学习】Machine-Learning模型与算法应用—使用Adaboost建模及工作环境下的数据分析整理
  • (NO.00004)iOS实现打砖块游戏(十二):伸缩自如,我是如意金箍棒(上)!
  • (八)Spring源码解析:Spring MVC
  • (博弈 sg入门)kiki's game -- hdu -- 2147
  • (第30天)二叉树阶段总结
  • (二)PySpark3:SparkSQL编程
  • (附源码)springboot家庭财务分析系统 毕业设计641323
  • (附源码)ssm高校社团管理系统 毕业设计 234162
  • (附源码)计算机毕业设计ssm基于Internet快递柜管理系统
  • (免费领源码)python+django+mysql线上兼职平台系统83320-计算机毕业设计项目选题推荐
  • (十一)手动添加用户和文件的特殊权限