2022-12-22:给定一个数字n,代表数组的长度, 给定一个数字m,代表数组每个位置都可以在1~m之间选择数字, 所有长度为n的数组中,最长递增子序列长度为3的数组,叫做达标数组。 返回达标数组的
2022-12-22:给定一个数字n,代表数组的长度,
给定一个数字m,代表数组每个位置都可以在1~m之间选择数字,
所有长度为n的数组中,最长递增子序列长度为3的数组,叫做达标数组。
返回达标数组的数量。
1 <= n <= 500,
1 <= m <= 10,
500 * 10 * 10 * 10,
结果对998244353取模,
实现的时候没有取模的逻辑,因为非重点。
来自微众银行。
答案2022-12-22:
参考最长递增子序列。
代码用rust编写。代码如下:
use std::iter::repeat;
fn main() {
println!("功能测试开始");
for n in 4..=8 {
for m in 1..=5 {
let ans1 = number1(n, m);
let ans2 = number2(n, m);
if ans1 != ans2 {
println!("{}", ans1);
println!("{}", ans2);
println!("出错了!");
}
}
}
println!("功能测试结束");
}
// 暴力方法
// 为了验证
fn number1(n: i32, m: i32) -> i32 {
let mut a: Vec<i32> = repeat(0).take(n as usize).collect();
return process1(0, n, m, &mut a);
}
fn process1(i: i32, n: i32, m: i32, path: &mut Vec<i32>) -> i32 {
if i == n {
return if length_of_lis(path) == 3 { 1 } else { 0 };
} else {
let mut ans = 0;
for cur in 1..=m {
path[i as usize] = cur;
ans += process1(i + 1, n, m, path);
}
return ans;
}
}
fn length_of_lis(arr: &mut Vec<i32>) -> i32 {
if arr.len() == 0 {
return 0;
}
let mut ends: Vec<i32> = repeat(0).take(arr.len()).collect();
ends[0] = arr[0];
let mut right = 0;
let mut max = 1;
for i in 1..arr.len() as i32 {
let mut l = 0;
let mut r = right;
while l <= r {
let mut m = (l + r) / 2;
if arr[i as usize] > ends[m as usize] {
l = m + 1;
} else {
r = m - 1;
}
}
right = get_max(right, l);
ends[l as usize] = arr[i as usize];
max = get_max(max, l + 1);
}
return max;
}
fn get_max<T: Clone + Copy + std::cmp::PartialOrd>(a: T, b: T) -> T {
if a > b {
a
} else {
b
}
}
// i : 当前来到的下标
// f、s、t : ends数组中放置的数字!
// ? == 0,没放!
// n : 一共的长度!
// m : 每一位,都可以在1~m中随意选择数字
// 返回值:i..... 有几个合法的数组!
fn zuo(i: i32, f: i32, s: i32, t: i32, n: i32, m: i32) -> i32 {
if i == n {
return if f != 0 && s != 0 && t != 0 { 1 } else { 0 };
}
// i < n
let mut ans = 0;
for cur in 1..=m {
if f == 0 || f >= cur {
ans += zuo(i + 1, cur, s, t, n, m);
} else if s == 0 || s >= cur {
ans += zuo(i + 1, f, cur, t, n, m);
} else if t == 0 || t >= cur {
ans += zuo(i + 1, f, s, cur, n, m);
}
}
return ans;
}
// 正式方法
// 需要看最长递增子序列!
// 尤其是理解ends数组的意义!
fn number2(n: i32, m: i32) -> i32 {
//repeat(vec![]).take((m+1) as usize).collect();
let mut dp: Vec<Vec<Vec<Vec<i32>>>> = repeat(
repeat(
repeat(repeat(-1).take((m + 1) as usize).collect())
.take((m + 1) as usize)
.collect(),
)
.take((m + 1) as usize)
.collect(),
)
.take(n as usize)
.collect();
return process2(0, 0, 0, 0, n, m, &mut dp);
}
fn process2(
i: i32,
f: i32,
s: i32,
t: i32,
n: i32,
m: i32,
dp: &mut Vec<Vec<Vec<Vec<i32>>>>,
) -> i32 {
if i == n {
return if f != 0 && s != 0 && t != 0 { 1 } else { 0 };
}
if dp[i as usize][f as usize][s as usize][t as usize] != -1 {
return dp[i as usize][f as usize][s as usize][t as usize];
}
let mut ans = 0;
for cur in 1..=m {
if f == 0 || cur <= f {
ans += process2(i + 1, cur, s, t, n, m, dp);
} else if s == 0 || cur <= s {
ans += process2(i + 1, f, cur, t, n, m, dp);
} else if t == 0 || cur <= t {
ans += process2(i + 1, f, s, cur, n, m, dp);
}
}
dp[i as usize][f as usize][s as usize][t as usize] = ans;
return ans;
}

2022-12-22:给定一个数字n,代表数组的长度, 给定一个数字m,代表数组每个位置都可以在1~m之间选择数字, 所有长度为n的数组中,最长递增子序列长度为3的数组,叫做达标数组。 返回达标数组的的更多相关文章
- POJ 2533 - Longest Ordered Subsequence - [最长递增子序列长度][LIS问题]
题目链接:http://poj.org/problem?id=2533 Time Limit: 2000MS Memory Limit: 65536K Description A numeric se ...
- 编程之美 set 7 求数组中的最长递增子序列
解法 1. 假设在目标数组 array[] 的前 i 个元素中, 最长递增子序列的长度为 LIS[i] 那么状态转移方程为 LIS[i] = max(1, LIS[k]+1) array[i+1] & ...
- 动态规划 - 最长递增子序列(LIS)
最长递增子序列是动态规划中经典的问题,详细如下: 在一个已知的序列{a1,a2,...,an}中,取出若干数组组成新的序列{ai1,ai2,...,aim},其中下标i1,i2,...,im保持递增, ...
- 最长递增子序列(LIS)(转)
最长递增子序列(LIS) 本博文转自作者:Yx.Ac 文章来源:勇幸|Thinking (http://www.ahathinking.com) --- 最长递增子序列又叫做最长上升子序列 ...
- 算法之动态规划(最长递增子序列——LIS)
最长递增子序列是动态规划中最经典的问题之一,我们从讨论这个问题开始,循序渐进的了解动态规划的相关知识要点. 在一个已知的序列 {a1, a 2,...an}中,取出若干数组成新的序列{ai1, ai ...
- 【LeetCode】300.最长递增子序列——暴力递归(O(n^3)),动态规划(O(n^2)),动态规划+二分法(O(nlogn))
算法新手,刷力扣遇到这题,搞了半天终于搞懂了,来这记录一下,欢迎大家交流指点. 题目描述: 给你一个整数数组 nums ,找到其中最长严格递增子序列的长度. 子序列是由数组派生而来的序列,删除(或不删 ...
- 51nod 1376 最长递增子序列的数量(线段树)
51nod 1376 最长递增子序列的数量 数组A包含N个整数(可能包含相同的值).设S为A的子序列且S中的元素是递增的,则S为A的递增子序列.如果S的长度是所有递增子序列中最长的,则称S为A的最长递 ...
- 动态规划----最长递增子序列问题(LIS)
题目: 输出最长递增子序列的长度,如输入 4 2 3 1 5 6,输出 4 (因为 2 3 5 6组成了最长递增子序列). 暴力破解法:这种方法很简单,两层for循环搞定,时间复杂度是O(N2). 动 ...
- 300. Longest Increasing Subsequence(LIS最长递增子序列 动态规划)
Given an unsorted array of integers, find the length of longest increasing subsequence. For example, ...
- 最长递增子序列(LIS)
最长递增子序列(Longest Increasing Subsequence) ,我们简记为 LIS. 题:求一个一维数组arr[i]中的最长递增子序列的长度,如在序列1,-1,2,-3,4,-5,6 ...
随机推荐
- 3---java中的集合
集合是什么:表示一组元素的对象,有的是有序的,有的是无序的,有的是可重复的,有的是不可重复的. 首先根是:Collection 1:Set 没有重复元素 SortedSet 有序的Set 2:Lis ...
- 01.html大致主体格式
<!DOCTYPE html> 不是HTML标签,就是文档声明标签 告诉浏览器使用哪种html版本来显示网页,其必须在文档中的最前面位置,要放在<html>标签之前, < ...
- pom文件信息的解析
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://mave ...
- c++中文编码格式
c++程序中涉及到中文字符的输入输出以及其他操作经常会出现乱码.乱码主要是由于程序的源文件编码.可执行文件编码以及程序运行环境的编码不匹配导致.比如,c++源程序文件编码为GB18030, 在源程序中 ...
- 写.jsp项目有感
本次练习了一个简单的登录界面 我觉得在写这种类型的界面的时候,需要将各个需求分开,就以这次的登录界面为例展开说说 1.登录界面 输入框的居中问题.登录按钮的跳转问题.验证码图片的随机问题.快速注册的跳 ...
- Qt 学习笔记 - 第五章 - Qt 时间编程 - Qt 时钟
原文地址:Qt 学习笔记 - 第五章 - Qt 时间编程 - Qt 时钟 Qt 学习笔记全系列传送门: Qt 学习笔记 - 第一章 - 快速开始.信号与槽 Qt 学习笔记 - 第二章 - 添加图片.布 ...
- Linux & 标准C语言学习 <DAY9_1>
2.函数传参: 1.函数中定义的变量属于该函数,出了该函数就不能再被别的函数直接使用 2.实参与形参之间是以赋值的方式进行传递数据的,并且是单项值传递 ...
- RunnerGo可视化场景管理,还原真实场景
在进行性能测试时,测试场景的正确配置非常关键.首先,需要根据业务场景和需求,设计出合理的测试场景,再利用相应的工具进行配置,实现自动化的性能测试. 在JMeter中,用户需要自己组织测试场景,或是在同 ...
- vue中的v-model 与 .sync
<input v-model="parentData"> //等同于 <input :value="parentData" @input=&q ...
- 这可能是最全面的TCP面试八股文了
计算机网络基础,考验一个程序员的基本功,也能更快的筛选出更优秀的人才. 说说TCP的三次握手 假设发送端为客户端,接收端为服务端.开始时客户端和服务端的状态都是CLOSED. 第一次握手:客户端向服务 ...