2022-11-20:小团生日收到妈妈送的两个一模一样的数列作为礼物!
他很开心的把玩,不过不小心没拿稳将数列摔坏了!
现在他手上的两个数列分别为A和B,长度分别为n和m。
小团很想再次让这两个数列变得一样。他现在能做两种操作:
操作一是将一个选定数列中的某一个数a改成数b,这会花费|b-a|的时间,
操作二是选择一个数列中某个数a,将它从数列中丢掉,花费|a|的时间。
小团想知道,他最少能以多少时间将这两个数列变得再次相同!
输入描述:
第一行两个空格隔开的正整数n和m,分别表示数列A和B的长度。
接下来一行n个整数,分别为A1 A2…An
接下来一行m个整数,分别为B1 B2…Bm
对于所有数据,1 ≤ n,m ≤ 2000, |Ai|,|Bi| ≤ 10000
输出一行一个整数,表示最少花费时间,来使得两个数列相同。
来自美团。8.20笔试。

答案2022-11-20:

尝试模型。递归。

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

use std::iter::repeat;

fn main() {
let mut nums1 = vec![2, 1000, 2000];
let mut nums2 = vec![999, 1, 2003];
let ans = min_cost(&mut nums1, &mut nums2);
println!("ans = {:?}", ans);
} // A B
// zuo(A,B,0,0)
// A[ai.....] 对应 B[bi.....]
// 请变一样
// 返回最小代价
fn zuo(aa: &mut Vec<i32>, bb: &mut Vec<i32>, ai: i32, bi: i32) -> i32 {
if ai == aa.len() as i32 && bi == bb.len() as i32 {
return 0;
}
if ai != aa.len() as i32 && bi == bb.len() as i32 {
return aa[ai as usize] + zuo(aa, bb, ai + 1, bi);
}
if ai == aa.len() as i32 && bi != bb.len() as i32 {
return bb[bi as usize] + zuo(aa, bb, ai, bi + 1);
}
// A[ai] 有数 B[bi] 有数
// 可能性1 : 删掉A[ai]
let p1 = aa[ai as usize] + zuo(aa, bb, ai + 1, bi);
// 可能性2 : 删掉B[bi]
let p2 = bb[bi as usize] + zuo(aa, bb, ai, bi + 1);
// 可能性3 : 同时删掉
// int p3 = A[ai] + B[bi] + zuo(A, B, ai + 1, bi + 1);
// 可能性4 : 变!A[ai] -> B[bi] B[bi] -> A[ai]
let p4 = if aa[ai as usize] >= bb[bi as usize] {
aa[ai as usize] - bb[bi as usize]
} else {
bb[ai as usize] - aa[bi as usize]
} + zuo(aa, bb, ai + 1, bi + 1);
// 可能性5 : A[ai] == B[bi]
return get_min(p1, get_min(p2, p4));
} fn get_min<T: Clone + Copy + std::cmp::PartialOrd>(a: T, b: T) -> T {
if a < b {
a
} else {
b
}
} fn min_cost(aa: &mut Vec<i32>, bb: &mut Vec<i32>) -> i32 {
let n = aa.len() as i32;
let m = bb.len() as i32;
let mut dp: Vec<Vec<i32>> = repeat(repeat(-1).take((m + 1) as usize).collect())
.take((n + 1) as usize)
.collect();
return change2(aa, bb, 0, 0, &mut dp);
} // 暴力递归
// A[indexA....]和B[indexB....]完全一样
// 需要付出最少的代价返回
fn change(aa: &mut Vec<i32>, bb: &mut Vec<i32>, index_a: i32, index_b: i32) -> i32 {
if index_a == aa.len() as i32 && index_b == bb.len() as i32 {
return 0;
}
if index_a == aa.len() as i32 && index_b != bb.len() as i32 {
return bb[index_b as usize] + change(aa, bb, index_a, index_b + 1);
}
if index_a != aa.len() as i32 && index_b == bb.len() as i32 {
return aa[index_a as usize] + change(aa, bb, index_a + 1, index_b);
}
// indexA、indexB都没到最后
// 可能性1,丢掉A[indexA]
let p1 = aa[index_a as usize] + change(aa, bb, index_a + 1, index_b);
// 可能性2,丢掉B[indexB]
let p2 = bb[index_b as usize] + change(aa, bb, index_a, index_b + 1);
// 可能性3,同时丢掉A[indexA]、B[indexB]
// 可能性4,把A[indexA]改成B[indexB](也是B[indexB]改成A[indexA],因为代价一样)
// 可能性5,A[indexA]本来就是等于B[indexB]的,改的代价为0
// 可以分析出可能性3,肯定是不如可能性4、可能性5的
// 所以舍弃掉可能性3
let p45 = if aa[index_a as usize] - bb[index_b as usize] > 0 {
aa[index_a as usize] - bb[index_b as usize]
} else {
bb[index_b as usize] - aa[index_a as usize]
} + change(aa, bb, index_a + 1, index_b + 1);
return get_min(get_min(p1, p2), p45);
} // 上面的暴力递归方法改动态规划
fn change2(
aa: &mut Vec<i32>,
bb: &mut Vec<i32>,
index_a: i32,
index_b: i32,
dp: &mut Vec<Vec<i32>>,
) -> i32 {
if index_a == aa.len() as i32 && index_b == bb.len() as i32 {
return 0;
}
if dp[index_a as usize][index_b as usize] != -1 {
return dp[index_a as usize][index_b as usize];
}
let mut ans = 0;
if index_a == aa.len() as i32 && index_b != bb.len() as i32 {
ans = bb[index_b as usize] + change2(aa, bb, index_a, index_b + 1, dp);
} else if index_a != aa.len() as i32 && index_b == bb.len() as i32 {
ans = aa[index_a as usize] + change2(aa, bb, index_a + 1, index_b, dp);
} else {
let p1 = aa[index_a as usize] + change2(aa, bb, index_a + 1, index_b, dp);
let p2 = bb[index_b as usize] + change2(aa, bb, index_a, index_b + 1, dp);
let p45 = if aa[index_a as usize] - bb[index_b as usize] > 0 {
aa[index_a as usize] - bb[index_b as usize]
} else {
bb[index_b as usize] - aa[index_a as usize]
} + change2(aa, bb, index_a + 1, index_b + 1, dp);
ans = get_min(get_min(p1, p2), p45);
}
dp[index_a as usize][index_b as usize] = ans;
return ans;
}

执行结果如下:


左神java代码

2022-11-20:小团生日收到妈妈送的两个一模一样的数列作为礼物! 他很开心的把玩,不过不小心没拿稳将数列摔坏了! 现在他手上的两个数列分别为A和B,长度分别为n和m。 小团很想再次让这两个数列变的更多相关文章

  1. 2022.02.20 SA

    2022.02.20 SA 如果我还能看见明天黎明,如果我还能再爬起来,我仍会走我的路,哪怕这条路已经荒废许久,也许我们无法拥有感情,我们甚至无法像个正常人一样接受太阳的洗礼,但是我依然会执行我的条约 ...

  2. Android融合推送MixPush SDK集成多家推送平台,共享系统级推送,杀死APP也能收到推送

    消息推送是App运营的重要一环,为了优化消息推送成功率,降低电量和流量消耗,系统级的推送服务显得尤为重要.小米和魅族由此推出了自家的推送平台,在MIUI和Flyme上共享系统级推送服务,让APP在被杀 ...

  3. uni-app + .NET 7实现微信小程序订阅消息推送

    微信小程序的订阅消息是小程序的重要能力之一,为实现服务的闭环提供更优的体验.订阅消息我们应该经常见到,比如下单成功之后的服务通知,支付成功后的支付成功通知,都属于小程序的订阅消息. 本文只实现一次性订 ...

  4. iOS 疑难杂症— — 收到推送显示后自动消失的问题

    声明 欢迎转载,但请保留文章原始出处:) 博客园:http://www.cnblogs.com 农民伯伯: http://over140.cnblogs.com 问题 正在支持 Remote Noti ...

  5. php:比较两个txt文件,格式如下,分别取出a.txt有的b.txt没有的,b.txt有的a.txt没有的及两个都有的

    <?php /*比较两个txt文件,格式如下,分别取出a.txt有的b.txt没有的,b.txt有的a.txt没有的及两个都有的 * a.txt: * A * B * C * D * b.txt ...

  6. (11.20)Java小知识!

      经过一段时间的学习,我也终于来到了Java语言的核心篇,也就是对象与类的学习,今天想要和大家分享的是关于类的小知识点. 1.类的声明: 类可以看成创建Java对象的模板.类亦可以理解成Java一种 ...

  7. 20道C#练习题(二)11——20题

    11.一个游戏,前20关是每一关自身的分数,1-30关每一关是10分,31-40关,每一关是20分,1-49关,每一关是30分,第50关是100分,输入你现在闯到的关卡数,求你现在拥有的分数.利用if ...

  8. 剑桥offer(11~20)

    11.题目描述 输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示. class Solution { public: int NumberOf1(int n) { ; unsigned ...

  9. Java基础部分(11~20)

    11."=="和 equals 方法究竟有什么区别? (单独把一个东西说清楚,然后再说清楚另一个,这样,它们的区别自然就出来了,混在一起说,则很难说清楚) ==操作符专门用来比较两 ...

  10. 软件工程项目组Z.XML会议记录 2013/11/20

    软件工程项目组Z.XML会议记录 [例会时间]2013年11月20日星期三21:00-22:00 [例会形式]小组讨论 [例会地点]学生公寓3号楼会客厅 [例会主持]李孟 [会议记录]李孟 会议整体流 ...

随机推荐

  1. P3128 [USACO15DEC]Max Flow P(树上倍增和树链剖分)

    思路1(树上倍增$ + $树上差分) 每次都修改一条从\(u\)到\(v\),不就是树上差分的专门操作吗?? 直接用倍增求\(LCA\),每次\(d[u]++,d[v]++,d[LCA(u,v)]-- ...

  2. Conda 创建、激活、克隆、删除虚拟环境 - 搬运

    Conda 创建.激活.克隆.删除虚拟环境 转自 :https://zhuanlan.zhihu.com/p/547724114 风影忍着   通常来说,对于每一个新的项目,我们都需要创建一个新的环境 ...

  3. .Net中跨域问题的解决方案

    开发中前端与后端完全分离并分开发布,遇到跨域问题,一通百度之后,解决方案如下: 把下面的代码放在web.config文件中的 System.WebServer 节点下 <httpProtocol ...

  4. PHP 循环语句

    循环机构,在一定的控制下,对此执行. 在PHP中,有以下几种循环 for循环.while循环.do-while循环.forech循环(针对数组) for 循环 语法 for (条件1;条件2;条件3) ...

  5. 重学c#系列—— explicit、implicit与operator[三十四]

    前言 我们都知道operator 可以对我们的操作符进行重写,那么explicit 和 implicit 就是对转换的重写. 正文 explicit 就是强制转换,然后implicit 就是隐式转换. ...

  6. java面向对象-类与对象,构造器

    java面向对象-类与对象,构造器 类与对象 package charpter5.Demo; public class Student { //属性:字段 static String name2=&q ...

  7. Teamcenter_NX集成开发:UF_UGMGR函数的使用

    最近工作中经常使用Teamcenter.NX集成开发的情况,因此在这里记录UF_UGMGR函数的使用.使用UF_UGMGR相关函数需要有Teamcenter使用经验,理解Teamcenter中文件夹. ...

  8. 在已有的vue项目中添加单元测试模块

    package.json 添加新命令 "test": "jest",下载包: "jest": "^26.6.3", &q ...

  9. go微服务框架kratos学习笔记二(kratos demo 结构)

    目录 api cmd configs dao di model server service 上篇文章go微服务框架kratos学习笔记一(kratos demo)跑了kratos demo 本章来看 ...

  10. 在Ubuntu 18.04上安装NVIDIA

    安装NVIDIA显卡驱动风险极大,新手注意. 在Ubuntu 18.04上安装NVIDIA有三种方法: 使用标准Ubuntu仓库进行自动化安装 使用PPA仓库进行自动化安装 使用官方的NVIDIA驱动 ...