2022-07-29:一共有n个人,从左到右排列,依次编号0~n-1,
h[i]是第i个人的身高,
v[i]是第i个人的分数,
要求从左到右选出一个子序列,在这个子序列中的人,从左到右身高是不下降的。
返回所有符合要求的子序列中,分数最大累加和是多大。
n <= 10的5次方, 1 <= h[i] <= 10的9次方, 1 <= v[i] <= 10的9次方。
来自字节。

答案2022-07-29:

线段树。

代码用rust编写。代码如下:

use rand::Rng;
fn main() {
let nn: i32 = 30;
let vv: i32 = 100;
let test_time: i32 = 20000;
println!("测试开始");
for _ in 0..test_time {
let n = rand::thread_rng().gen_range(0, nn) + 1;
let mut h = random_array(n, vv);
let mut v = random_array(n, vv);
if right(&mut h, &mut v) != max_sum(&mut h, &mut v) {
println!("出错了!");
break;
}
}
println!("测试结束");
} // 为了测试
// 绝对正确的暴力方法
fn right(h: &mut Vec<i32>, v: &mut Vec<i32>) -> i32 {
return process(h, v, 0, 0);
} fn process(h: &mut Vec<i32>, v: &mut Vec<i32>, index: i32, pre_value: i32) -> i32 {
if index == h.len() as i32 {
return 0;
}
let p1 = process(h, v, index + 1, pre_value);
let p2 = if h[index as usize] >= pre_value {
v[index as usize] + process(h, v, index + 1, h[index as usize])
} else {
0
};
return get_max(p1, p2);
} fn get_max<T: Clone + Copy + std::cmp::PartialOrd>(a: T, b: T) -> T {
if a > b {
a
} else {
b
}
} // 正式方法
// 时间复杂度O(N * logN)
fn max_sum(h: &mut Vec<i32>, v: &mut Vec<i32>) -> i32 {
let n = h.len() as i32;
let mut rank0 = h.clone();
rank0.sort();
let mut st = SegmentTree::new(n);
for i in 0..n {
let height = rank(&mut rank0, h[i as usize]);
// 1~height max
let t = st.max1(height);
st.update1(height, t + v[i as usize]);
}
return st.max1(n);
} // [150, 152, 160, 175] 160
// 1 2 3 4
// 3
fn rank(rank0: &mut Vec<i32>, num: i32) -> i32 {
let mut l = 0;
let mut r = rank0.len() as i32 - 1;
let mut m = 0;
let mut ans = 0;
while l <= r {
m = (l + r) / 2;
if rank0[m as usize] >= num {
ans = m;
r = m - 1;
} else {
l = m + 1;
}
}
return ans + 1;
} pub struct SegmentTree {
pub n: i32,
pub max: Vec<i32>,
pub update: Vec<i32>,
} impl SegmentTree {
pub fn new(max_size: i32) -> Self {
let n = max_size + 1;
let mut max: Vec<i32> = vec![];
let mut update: Vec<i32> = vec![];
for _ in 0..n << 2 {
max.push(0);
update.push(-1);
}
Self { n, max, update }
} pub fn update1(&mut self, index: i32, c: i32) {
self.update0(index, index, c, 1, self.n, 1);
} pub fn max1(&mut self, right: i32) -> i32 {
return self.max0(1, right, 1, self.n, 1);
} fn push_up(&mut self, rt: i32) {
self.max[rt as usize] = get_max(
self.max[(rt << 1) as usize],
self.max[(rt << 1 | 1) as usize],
);
} fn push_down(&mut self, rt: i32, _ln: i32, _rn: i32) {
if self.update[rt as usize] != -1 {
self.update[(rt << 1) as usize] = self.update[rt as usize];
self.max[(rt << 1) as usize] = self.update[rt as usize];
self.update[(rt << 1 | 1) as usize] = self.update[rt as usize];
self.max[(rt << 1 | 1) as usize] = self.update[rt as usize];
self.update[rt as usize] = -1;
}
} fn update0(&mut self, ll: i32, rr: i32, cc: i32, l: i32, r: i32, rt: i32) {
if ll <= l && r <= rr {
self.max[rt as usize] = cc;
self.update[rt as usize] = cc;
return;
}
let mid = (l + r) >> 1;
self.push_down(rt, mid - l + 1, r - mid);
if ll <= mid {
self.update0(ll, rr, cc, l, mid, rt << 1);
}
if rr > mid {
self.update0(ll, rr, cc, mid + 1, r, rt << 1 | 1);
}
self.push_up(rt);
} fn max0(&mut self, ll: i32, rr: i32, l: i32, r: i32, rt: i32) -> i32 {
if ll <= l && r <= rr {
return self.max[rt as usize];
}
let mid = (l + r) >> 1;
self.push_down(rt, mid - l + 1, r - mid);
let mut ans = 0;
if ll <= mid {
ans = get_max(ans, self.max0(ll, rr, l, mid, rt << 1));
}
if rr > mid {
ans = get_max(ans, self.max0(ll, rr, mid + 1, r, rt << 1 | 1));
}
return ans;
}
} // 为了测试
fn random_array(n: i32, v: i32) -> Vec<i32> {
let mut ans: Vec<i32> = vec![];
for _ in 0..n {
ans.push(rand::thread_rng().gen_range(0, v) + 1);
}
return ans;
}

执行结果如下:


左神java代码

2022-07-29:一共有n个人,从左到右排列,依次编号0~n-1, h[i]是第i个人的身高, v[i]是第i个人的分数, 要求从左到右选出一个子序列,在这个子序列中的人,从左到右身高是不下降的。的更多相关文章

  1. 《剑指Offer》第1题(Java实现):在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

    一.题目描述 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该 ...

  2. Android 4.2原生支持从右到左的文字排列格式

    Android 4.1(Jelly Bean)  在TextView和EditText 元素里对“双向文字顺序”提供了有限的功能支持,允许应用程序在编辑和显示字符的时候,能够同时支持从左到右(LTR) ...

  3. javascript小实例,编写一个方法,实现从n-m个数中随机选出一个整数

    别怪我是一个闷葫芦,没那么多花哨的语言,废话不多说,先说说小实例的要求: 编写一个方法,实现从n-m个数中随机选出一个整数,要求:传递的参数不足两个或者不是有效数字,返回[0-1]之间的随机数,需要解 ...

  4. 07/29/2013 02:10:02 AM - CMDPHP: Poller[0] Host[6] DS[10] WARNING: Result from SNMP not valid. Partial Result: U

    snmpwalk -c public -v2c  客户端ip地址  自定义的oid  能取到数据,但是服务器端就是图片一片空白 rrdtool fetch 文件名.rrd 查看到的全都是nan cac ...

  5. JZOJ 2022.07.06【提高组A】模拟

    历程 被暴打了 原因是钻进了 \(T4\) 的坑中... 先看完题,发现 \(T4\) 比较有意思,\(T2\) 没有想法 \(T3\) 挺容易,做法似乎很好想 \(T1\) 送分,十几分钟搞定 然后 ...

  6. 2018.07.29~30 uoj#170. Picks loves segment tree VIII(线段树)

    传送门 线段树好题. 维护区间取两种最值,区间加,求区间两种历史最值,区间最小值. 自己的写法调了一个晚上+一个上午+一个下午+一个晚上并没有调出来,90" role="prese ...

  7. python 一个二维数组和一个整数,判断数组中是否含有该整数

    在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序. 请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. de ...

  8. 算法:Manacher,给定一个字符串str,返回str中最长回文子串的长度。

    [题目] 给定一个字符串str,返回str中最长回文子串的长度 [举例] str="123", 1 str="abc1234321ab" 7 [暴力破解] 从左 ...

  9. extract()函数:用于从一个date或者interval类型中截取到特定的部分

    extract()函数:用于从一个date或者interval类型中截取到特定的部分 ### extract 语法extract ( { year | month | day | hour | min ...

  10. C语言:把分数最低的学生数据放入数组b所指的数组中,-从键盘输入若干字符串,写入文件myfile4中,用-1作字符输入结束的标志,

    //学生记录由学号和成绩组成,N名学生的数据已放入主函数中的结构体数组中,fun函数:把分数最低的学生数据放入数组b所指的数组中,分数最低的学生可能不止一个.人数返回. #include <st ...

随机推荐

  1. Linux 系统设置

    ubuntu下使用PageUp/PageDown快速翻出历史命令 #vim/etc/inputrc 解除两行注视后重启终端 "\e[5~": history-search-back ...

  2. Linux系统mysql免安装版配置指南

    1.下载(/usr/local目录) wget https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.32-linux-glibc2.12-x ...

  3. 三天吃透MySQL面试八股文

    本文已经收录到Github仓库,该仓库包含计算机基础.Java基础.多线程.JVM.数据库.Redis.Spring.Mybatis.SpringMVC.SpringBoot.分布式.微服务.设计模式 ...

  4. 在java中String类为什么要设计成final?Java面试常见问题

    2023Java面试题最经典的问题之一了,非常经典的Java基础知识,一定要学会! 在Java中,String类被设计成final,这意味着它的值在创建后不可更改.这是因为字符串在Java中使用广泛, ...

  5. C++ 用户输入验证

    在编写程序时,请考虑用户将如何滥用您的程序,尤其是在文本输入方面.对于每个文本输入点,请考虑: 会不会提取失败? 用户可以输入比预期更多的输入吗? 用户可以输入无意义的输入吗 用户可以溢出输入吗? 以 ...

  6. PHP 图片的合并,微信小程序码合并,文字合并

    //业务需求:我们需要一个微信小程序码,但是是需要提供给别人扫码的但是只有一个纯粹的小程序码是不好看的,所以需要推广的海报图片.再结合文字 最终效果 准备工作  1.需要海报的底图  2.小程序码的图 ...

  7. nodsjs POST请求

    PHP 遇到问题: 1.跨域问题 报failed to load response data:no data fond for response with give header("Cont ...

  8. 比memcpy还要快的内存拷贝,老哥了解一下?

    本文来自博客园,作者:T-BARBARIANS,转载请注明原文链接:https://www.cnblogs.com/t-bar/p/17262147.html 谢谢! 前言 朋友们有想过居然还有比me ...

  9. 搭建私有YUM仓库_及_内网镜像站

    搭建私有YUM仓库_及_内网镜像站 搭建私有YUM仓库(自己定制的rpm包)私有yum仓库环境系统版本:centos7.4 IP:192.168.1.47 #最好能上公网 私有yum仓库服务端配置 第 ...

  10. [GIT]指定分支下创建分支

    1 解决方案 Eg: master分支下创建 $ git checkout master //切换到master分支下 $ git branch branch_tmp_A //在本地仓库创建临时分支b ...