2022-12-12:有n个城市,城市从0到n-1进行编号。小美最初住在k号城市中
在接下来的m天里,小美每天会收到一个任务
她可以选择完成当天的任务或者放弃该任务
第i天的任务需要在ci号城市完成,如果她选择完成这个任务
若任务开始前她恰好在ci号城市,则会获得ai的收益
若她不在ci号城市,她会前往ci号城市,获得bi的收益
当天的任务她都会当天完成
任务完成后,她会留在该任务所在的ci号城市直到接受下一个任务
如果她选择放弃任务,她会停留原地,且不会获得收益
小美想知道,如果她合理地完成任务,最大能获得多少收益
输入描述: 第一行三个正整数n, m和k,表示城市数量,总天数,初始所在城市
第二行为m个整数c1, c2,… cm,其中ci表示第i天的任务所在地点为ci
第三行为m个整数a1, a2,… am,其中ai表示完成第i天任务且地点不变的收益
第四行为m个整数b1, b2,… bm,其中bi表示完成第i天的任务且地点改变的收益
0 <= k, ci <= n <= 30000
1 <= m <= 30000
0 <= ai, bi <= 10^9
输出描述 输出一个整数,表示小美合理完成任务能得到的最大收益。
来自美团。

答案2022-12-12:

1.递归。
时间复杂度:O(N2)。
空间复杂度:O(N
2)。

2.线段树。
时间复杂度:O(N*logN)。
空间复杂度:O(N**2)。

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

use rand::Rng;
use std::iter::repeat;
fn main() {
let nn: i32 = 100;
let mm: i32 = 100;
let vv: i32 = 10000;
let test_time: i32 = 5000;
println!("测试开始");
for i in 0..test_time {
let n: i32 = rand::thread_rng().gen_range(0, nn) + 1;
let m: i32 = rand::thread_rng().gen_range(0, mm) + 1;
let k: i32 = rand::thread_rng().gen_range(0, n);
let mut c = random_array(m, n);
let mut a = random_array(m, vv);
let mut b = random_array(m, vv);
let ans1 = max_porfit1(n, m, k, &mut c, &mut a, &mut b);
let ans2 = max_porfit2(n, m, k, &mut c, &mut a, &mut b);
if ans1 != ans2 {
println!("出错了!");
println!("i = {}", i);
println!("ans1 = {}", ans1);
println!("ans2 = {}", ans2);
break;
}
}
println!("测试结束");
} // 暴力方法
// 时间复杂度O(N^2)
// 为了验证
fn max_porfit1(
n: i32,
m: i32,
k: i32,
c: &mut Vec<i32>,
a: &mut Vec<i32>,
b: &mut Vec<i32>,
) -> i32 {
let mut dp: Vec<Vec<i32>> = repeat(repeat(-1).take(m as usize).collect())
.take(n as usize)
.collect();
return process1(k, 0, m, c, a, b, &mut dp);
} // cur : 小美当前在哪!
// i : 当前面临的是任务编号!
// m : 一共有多少任务,固定
// c[i] : 第i号任务要在哪个城里完成
// a[i] : 恰好在!收益
// b[i] : 赶过去!收益
// 返回 : i....... 小美获得的最大收益
fn process1(
cur: i32,
i: i32,
m: i32,
c: &mut Vec<i32>,
a: &mut Vec<i32>,
b: &mut Vec<i32>,
dp: &mut Vec<Vec<i32>>,
) -> i32 {
if i == m {
return 0;
}
if dp[cur as usize][i as usize] != -1 {
return dp[cur as usize][i as usize];
}
// 可能性1 : 不做任务,彻底放弃,留在原地
let p1 = process1(cur, i + 1, m, c, a, b, dp);
// 可能性2 : 做任务,要看看cur在哪,来获得收益
let mut p2 = 0;
if cur == c[i as usize] {
p2 = a[i as usize] + process1(c[i as usize], i + 1, m, c, a, b, dp);
} else {
p2 = b[i as usize] + process1(c[i as usize], i + 1, m, c, a, b, dp);
}
let ans = get_max(p1, p2);
dp[cur as usize][i as usize] = ans;
return ans;
} 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_porfit2(
n: i32,
m: i32,
k: i32,
c: &mut Vec<i32>,
a: &mut Vec<i32>,
b: &mut Vec<i32>,
) -> i32 {
let mut st = SegmentTree::new(n);
st.update(k, 0);
let mut ans = 0;
for i in 0..m {
// c[i]
let cur_ans = get_max(
get_max(
st.max(0, c[i as usize] - 1),
st.max(c[i as usize] + 1, n - 1),
) + b[i as usize],
st.max(c[i as usize], c[i as usize]) + a[i as usize],
);
ans = get_max(ans, cur_ans);
st.update(c[i as usize], cur_ans);
}
return ans;
} struct SegmentTree {
n: i32,
max: Vec<i32>,
}
impl SegmentTree {
fn new(nn: i32) -> Self {
let n = nn;
let max: Vec<i32> = repeat(i32::MIN).take(((n + 1) << 2) as usize).collect();
Self { n, max }
} fn max(&mut self, mut l: i32, mut r: i32) -> i32 {
l += 1;
r += 1;
if l > r {
return i32::MIN;
}
return self.max0(l, r, 1, self.n, 1);
} fn update(&mut self, mut i: i32, v: i32) {
i += 1;
self.update0(i, i, v, 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 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] = get_max(self.max[rt as usize], cc);
return;
}
let mid = (l + r) >> 1;
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;
let mut left = i32::MIN;
let mut right = i32::MIN;
if ll <= mid {
left = self.max0(ll, rr, l, mid, rt << 1);
}
if rr > mid {
right = self.max0(ll, rr, mid + 1, r, rt << 1 | 1);
}
return get_max(left, right);
}
} // 为了测试
fn random_array(n: i32, v: i32) -> Vec<i32> {
let mut ans = vec![];
for i in 0..n {
ans.push(rand::thread_rng().gen_range(0, v));
}
ans
}

执行结果如下:


左神java代码

2022-12-12:有n个城市,城市从0到n-1进行编号。小美最初住在k号城市中 在接下来的m天里,小美每天会收到一个任务 她可以选择完成当天的任务或者放弃该任务 第i天的任务需要在ci号城市完成,的更多相关文章

  1. 《K&R》中引用的几个排序算法(shellsort、)以及一个自己乱写的排序

    留待期末考后更新... void shellsort(int v[], int n) { int gap, i, j, temp; ; gap > ; gap /= ) for(i = gap; ...

  2. socket (转,吴秦,http://www.cnblogs.com/skynet/archive/2010/12/12/1903949.html)

    Linux Socket编程(不限Linux)2010-12-12 21:58 by 吴秦 我们深谙信息交流的价值,那网络中进程之间如何通信,如我们每天打开浏览器浏览网页时,浏览器的进程怎么与web ...

  3. java的服务是每收到一个请求就新开一个线程来处理吗?tomcat呢?

    首先,服务器的实现不止有这两种方式. 先谈谈题主说的这两种服务器模型: 1.收到一个请求就处理,这个时候就不能处理新的请求,这种为阻塞 这个是单线程模型,无法并发,一个请求没处理完服务器就会阻塞,不会 ...

  4. macOS Monterey 12.12.2 (21D49) 正式版 ISO、IPSW、PKG 下载

    本站下载的 macOS Monterey 软件包,既可以拖拽到 Applications(应用程序)下直接安装,也可以制作启动 U 盘安装,或者在虚拟机中启动安装. 2022 年 1 月 27 日,m ...

  5. 关于2016.12.12——T1的反思:凸包的意义与应用

    2016.12.12 T1 给n个圆,保证圆圆相离,求将圆围起来的最小周长.n<=100 就像上图.考场上,我就想用切线的角度来做凸包.以圆心x,y排序,像点凸包一样,不过用两圆之间的下切线角度 ...

  6. java 时间格式化(2016.04.12 12:32:55)

    输入的时间格式如:2016.04.12 12:32:55所示: 想要获取一定格式的日期,时间的方法 String startString = "2016.04.25 12:25:44&quo ...

  7. ONVIF协议测试工具 ONVIF Device Test Tool 29 12.12 最新版

    ONVIF协议测试工具 ONVIF Device Test Tool 29 12.12 最新版 包含文档和工具,本人亲测,好用! http://download.csdn.net/detail/li_ ...

  8. 收到一个神盾局的offer,怎么样?

    漫威十一年系列总结性的电影<复联4>正在热映,而衍生出的一部和漫威宇宙关联的美剧<神盾局特工>,今年我也在陆陆续续地看.一开始预期的是一部特工加一些科幻或魔幻元素的剧集,就图看 ...

  9. 源码安装 qemu-2.0.0 及其依赖 glib-2.12.12

    源码安装qemu-2.0.0 下载源代码并解压 http://wiki.qemu-project.org/download/qemu-2.0.0.tar.bz2 .tar.gz 编译及安装: cd q ...

  10. 2020.12.12【NOIP提高B组】模拟 总结

    第一次来 B 组做,虚的很 T1: 容斥原理 比赛时也打了个大致,但挂了,只有 50 分. 赛后重构了一下代码,AC \(UPDATE:2020/12/13\ \ \ 14:10\) 思路: 像前缀和 ...

随机推荐

  1. 【BUUCTF]ACTF2020 新生赛Exec1write up

    根据题目分析,俺们要用ping命令! 打开靶机,输入127.0.0.1尝试提交,直接出现无过滤: 尝试管道符执行命令,常见管道符: 1.|(就是按位或),直接执行|后面的语句 2.||(就是逻辑或), ...

  2. 【桥接设计模式详解】Java/JS/Go/Python/TS不同语言实现

    [桥接设计模式详解]Java/JS/Go/Python/TS不同语言实现 简介 桥接模式(Bridge Pattern)是一种结构型设计模式,它将一个大类或一系列紧密相关的类拆分为抽象和实现两个独立的 ...

  3. 这篇文章汇聚33个BUG!来挑战一下,看看你能找出来几个?

    你好呀,我是歪歪. 前几天看到"Qunar技术沙龙"公众号推送了一篇关于他们举办了一场"Code Review大赛"的文章. 看到 Code Review 我很 ...

  4. 如何利用javaweb实现数据的可视化

    描述 之前一直使用html进行网页版的数据库查询啥的,没有图片的参与,也没有将一条条数据变成较为直观的图画形式,这就是来实现以下数据的图画形式 了解及基础说明 通过查阅资料,我首先了解到要是想实现数据 ...

  5. Teamcenter_NX集成开发:UF_UGMGR_invoke_pdm_server函数的使用

    之前了解到通过UFUN函数UF_UGMGR_invoke_pdm_server可以调用Teamcenter ITK函数,从而可以获取及编辑Teamcenter对象.UFUN中有样例代码,但是就是不知道 ...

  6. flutter widget---->FloatingActionButton

    在Flutter中说起Button,floatingActionButton用的也非常的多.今天我们就来学习一下. Simple Example import 'package:flutter/mat ...

  7. 手把手带你从0完成医疗行业影像图像检测三大经典模型InceptionV3-RestNet50-VGG16(附python源代码及数据库)——改变世界经典人工智能项目实战(一)手把手教学迁移学习

    目录 1.迁移学习简介 2.项目简介 3.糖尿病视网膜病变数据集 4.考虑类别不平衡问题 5.定义模型质量 6.定义损失函数 7.预处理图像 8.搭建迁移学习网络 VGG16 迁移学习网络 Incep ...

  8. put、delete、post、get四种传参方式

    PUT: this.$http.put('url', { modifyTime:this.sizeForm.modifyTime, mqttRes:this.sizeForm.mqttRes, udp ...

  9. 念一句咒语 AI 就帮我写一个应用,我人麻了...

    原文链接:https://forum.laf.run/d/232 作为人类,我们时常会有自己独特的想法和脑洞大开的创意.然而,这些想法往往因为成本过高而无法实现,毕竟每个人的能力和精力都是有限的,尤其 ...

  10. CTF-RE-学习记录-汇编

    八进制运算 加法表 1+1=2 1+2=3 2+2=4 1+3=4 2+3=5 3+3=6 1+4=5 2+4=6 3+4=7 4+4=10 1+5=6 2+5=7 3+5=8 4+5=11 5+5= ...