2023-07-02:给定一个1~N的排列,每次将相邻两数相加,可以得到新的序列,长度是N-1 再对新的序列,每次将相邻两数相加,可以得到新的序列,长度是N-2 这样下去可以最终只剩一个数字 比如 :
2023-07-02:给定一个1~N的排列,每次将相邻两数相加,可以得到新的序列,长度是N-1
再对新的序列,每次将相邻两数相加,可以得到新的序列,长度是N-2
这样下去可以最终只剩一个数字
比如 :
3 1 2 4
4 3 6
7 9
16
现在如果知道N,和最后的数字sum,反推最原始的序列是什么
如果有多个答案,返回字典序最小的那个
字典序看做所有数字拼起来的字符串字典序
比如
1, 10, 2... 拼起来是 1102...
1, 2, 3, 4... 拼起来是 1234...
认为 1, 10, 2...的字典序更小
如果给定的n和sum,有答案,返回一个N长度的答案数组
如果给定的n和sum,无答案,返回一个1长度的数组{ -1 }
输入 : N = 4, sum = 16
输出 : 3 1 2 4
输入 : N = 10, sum = 4116
输出 : 1 3 5 7 10 9 8 6 4 2
答案2023-07-02:
大体步骤如下:
1.创建一个二维动态数组dp,大小为(1<<(n+1))x(sums[n]+1)。
2.定义一个变量status,其初始值为((1 << (n + 1)) - 1) ^ 1。
3.如果n小于1或大于10,或者sum大于sums[n],则返回数组[-1]。
4.调用process函数处理状态status、剩余和rest、索引index、长度n、模数组modulus和动态数组dp,得到结果ans。
5.如果ans的值为-1,说明无法找到合适的序列,返回数组[-1]。
6.创建一个长度为n的答案数组ans,并初始化index为0,rest为sum。
7.当status不等于0时,执行以下循环:
将
dp[status][rest]的值赋给ans[index]。将
status异或上1 << ans[index],更新status。将
rest减去ans[index] * modulus[index],更新rest。将
index加1。
8.返回答案数组ans。
总的时间复杂度:O(2^N * sum),其中N为输入的n,sum为输入的sum。
总的空间复杂度:O(2^N * sum),包括二维动态数组dp的空间。
go语言代码如下:
package main
import "fmt"
var moduluses = [][]int{
{},
{1},
{1, 1},
{1, 2, 1},
{1, 3, 3, 1},
{1, 4, 6, 4, 1},
{1, 5, 10, 10, 5, 1},
{1, 6, 15, 20, 15, 6, 1},
{1, 7, 21, 35, 35, 21, 7, 1},
{1, 8, 28, 56, 70, 56, 28, 8, 1},
{1, 9, 36, 84, 126, 126, 84, 36, 9, 1},
}
var sums = []int{0, 1, 3, 9, 24, 61, 148, 350, 808, 1837, 4116}
func lsp(n int, sum int) []int {
if n < 1 || n > 10 || sum > sums[n] {
return []int{-1}
}
dp := make([][]int, 1<<(n+1))
for i := range dp {
dp[i] = make([]int, sums[n]+1)
}
status := ((1 << (n + 1)) - 1) ^ 1
if !process(status, sum, 0, n, moduluses[n], dp) {
return []int{-1}
}
ans := make([]int, n)
index := 0
rest := sum
for status != 0 {
ans[index] = dp[status][rest]
status ^= 1 << ans[index]
rest -= ans[index] * moduluses[n][index]
index++
}
return ans
}
func process(status int, rest int, index int, n int, modulus []int, dp [][]int) bool {
if rest < 0 {
return false
}
if status == 0 {
return rest == 0
}
if dp[status][rest] != 0 {
return dp[status][rest] != -1
}
ans := -1
if n == 10 && (status&(1<<10)) != 0 {
if process(status^(1<<10), rest-modulus[index]*10, index+1, n, modulus, dp) {
ans = 10
}
}
if ans == -1 {
for i := 1; i <= n; i++ {
if (status & (1 << i)) != 0 {
if process(status^(1<<i), rest-modulus[index]*i, index+1, n, modulus, dp) {
ans = i
break
}
}
}
}
dp[status][rest] = ans
return ans != -1
}
func main() {
N1 := 4
sum1 := 16
ans1 := lsp(N1, sum1)
for _, num := range ans1 {
fmt.Printf("%d ", num)
}
fmt.Println()
N2 := 10
sum2 := 4116
ans2 := lsp(N2, sum2)
for _, num := range ans2 {
fmt.Printf("%d ", num)
}
fmt.Println()
N3 := 10
sum3 := 3688
ans3 := lsp(N3, sum3)
for _, num := range ans3 {
fmt.Printf("%d ", num)
}
fmt.Println()
N4 := 10
sum4 := 4013
ans4 := lsp(N4, sum4)
for _, num := range ans4 {
fmt.Printf("%d ", num)
}
fmt.Println()
}


2023-07-02:给定一个1~N的排列,每次将相邻两数相加,可以得到新的序列,长度是N-1 再对新的序列,每次将相邻两数相加,可以得到新的序列,长度是N-2 这样下去可以最终只剩一个数字 比如 :的更多相关文章
- C语言100题集合005-删除一维数组中所有相同的数,使之只剩一个
系列文章<C语言经典100例>持续创作中,欢迎大家的关注和支持. 喜欢的同学记得点赞.转发.收藏哦- 后续C语言经典100例将会以pdf和代码的形式发放到公众号 欢迎关注:计算广告生态 即 ...
- docker PXC MYSQL集群节点启动失败/节点顺序消失/只剩一个节点存在问题的解决
转载于:https://my.oschina.net/u/4884318/blog/4908669 大牛 佩服此人 截取本人遇到的问题: "error:0407008A:rsa routin ...
- [您有新的未分配科技点]数位DP:从板子到基础(例题 bzoj1026 windy数 bzoj3131 淘金)
只会统计数位个数或者某种”符合简单规律”的数并不够……我们需要更多的套路和应用 数位dp中常用的思想是“分类讨论”思想.下面我们就看一道典型的分类讨论例题 1026: [SCOI2009]windy数 ...
- 已知w是一个大于10但不大于1000000的无符号整数,若w是n(n≥2)位的整数,则求出w的后n-1位的数。
描述 已知w是一个大于10但不大于1000000的无符号整数,若w是n(n≥2)位的整数,则求出w的后n-1位的数. 输入 第一行为M,表示测试数据组数.接下来M行,每行包含一个测试数据. 输出 ...
- Js:消息弹出框、获取时间区间、时间格式、easyui datebox 自定义校验、表单数据转化json、控制两个日期不能只填一个
(function ($) { $.messageBox = function (message) { $.messager.show({ title:'消息框提示', msg:message, sh ...
- 明明想在学校中请一些同学一起做一项问卷调查,为了实验的客观性,他先用计算机生成了N个1到1000之间的随机整数(N≤1000),对于其中重复的数字,只保留一个,把其余相同的数去掉,不同的数对应着不同的学生的学号。然后再把这些数从
明明想在学校中请一些同学一起做一项问卷调查,为了实验的客观性,他先用计算机生成了N个1到1000之间的随机整数(N≤1000),对于其中重复的数字,只保留一个,把其余相同的数去掉,不同的数对应着不同的 ...
- Android 实现两个list分别出现(在某一时刻只出现一个控件)
第一种方法: 在.xml文件中将这两个List分别放入不同的布局管理器中,比如说 <RelativeLayout android:layout_width="match_parent& ...
- 2021.07.02 P1383 高级打字机题解(可持久化平衡树)
2021.07.02 P1383 高级打字机题解(可持久化平衡树) 分析: 从可以不断撤销并且查询不算撤销这一骚操作可以肯定这是要咱建一棵可持久化的树(我也只会建可持久化的树,当然,还有可持久化并查集 ...
- 2021.07.02 UVa1197 多路归并模板
2021.07.02 UVa1197 多路归并模板 UVA11997 K Smallest Sums - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 分析: 题解 UVA11997 ...
- SqlSever基础 union 联合查询,厉害的并集 重复项只显示一个 两个查询结果并在一起后排序
镇场诗:---大梦谁觉,水月中建博客.百千磨难,才知世事无常.---今持佛语,技术无量愿学.愿尽所学,铸一良心博客.------------------------------------------ ...
随机推荐
- 【源码分析】XXL-JOB的执行器的注册流程
目的:分析xxl-job执行器的注册过程 流程: 获取执行器中所有被注解(@xxlJjob)修饰的handler 执行器注册过程 执行器中任务执行过程 版本:xxl-job 2.3.1 建议:下载xx ...
- shell脚本编程(一)
c81ba641-5ed7-4ab9-a7c0-e319e0f3890b 初识shell脚本编程 最近项目需求,需要了解下shell脚本编程,所以自己就必须玩玩了= = 初识shell脚本编程,找了几 ...
- 笔记:C++学习之旅---面向对象程序设计2
笔记:C++学习之旅---面向对象程序设计2 面向对象程序设计基于三个基本概念:数据抽象.继承和动态绑定. 继承和动态绑定对程序的编写有两方面的影响:一是我们可以更容易的定义与其他类相似但不完全相同的 ...
- NOIP 2021 备战计划
NOIP 2021 备战计划 复习知识点: 加粗表示一定去复习,?表示很可能不需要 线段树.树状数组:无论最近写多少遍都要去好好复习 Dij.SPFA:理由同上 大DP:哪个不重要? 门类:线性DP. ...
- 在算数运算中,能否将 bool 值 true 视作 1?
true == 1; true + 1; If the destination type is bool, see 4.12. If the source type is bool, the valu ...
- 2022-10-02:以下go语言代码能否通过编译?A: 能;B: 不能;C: 不知道。 package main import ( “fmt“ ) type worker interfa
2022-10-02:以下go语言代码能否通过编译?A: 能:B: 不能:C: 不知道. package main import ( "fmt" ) type worker int ...
- 2022-09-07:给你一个由正整数组成的数组 nums 。 数字序列的 最大公约数 定义为序列中所有整数的共有约数中的最大整数。 例如,序列 [4,6,16] 的最大公约数是 2 。 数组的一个
2022-09-07:给你一个由正整数组成的数组 nums . 数字序列的 最大公约数 定义为序列中所有整数的共有约数中的最大整数. 例如,序列 [4,6,16] 的最大公约数是 2 . 数组的一个 ...
- 2022-07-25:xiu是用rust语言编写的流媒体服务器软件项目。k8s安装xiu,drone文件如何写?
2022-07-25:xiu是用rust语言编写的流媒体服务器软件项目.k8s安装xiu,drone文件如何写? 答案2022-07-25: 云原生环境不可能完全一样,只能做参考. 我采用的是dron ...
- 2020-12-19:系统load过高,你怎么去查?
福哥答案2020-12-20:[答案来自此链接:](http://bbs.xiangxueketang.cn/question/800)1.top命令查看该机器的负载状况.2.cd /proc/pid ...
- 2022-05-16:A -> B,表示A认为B是红人, A -> B -> C,表示A认为B是红人,B认为C是红人,规定“认为”关系有传递性,所以A也认为C是红人, 给定一张有向图,方式是给定M个有
2022-05-16:A -> B,表示A认为B是红人, A -> B -> C,表示A认为B是红人,B认为C是红人,规定"认为"关系有传递性,所以A也认为C是红 ...