俄罗斯套娃问题的描述:
给定一些标记了宽度和高度的信封,宽度和高度以整数对形式(w, h)出现。当另一个信封的宽度和高度都比这个信封大的时候,这个信封就可以放进另一个信封里,如同俄罗斯套娃一样。请计算最多能有多少个信封能组成一组“俄罗斯套娃”信封(即可以把一个信封放到另一个信封里面)。
说明:不允许旋转信封
思路
建立一个矩阵,一行是长一行是宽
先按长进行排序,遇到长度相等的信封按宽继续排序
对比两次大小,大者即为结果
算法本质是LIS算法的一种变种,算是一种比较高效的方法总比穷举法好
代码
envelop <- read_csv(
"length,width
5,4
6,4
6,7
2,3
3,1
6,6
6,2"
)
LIS.num <- function(data_tibble){
return_c <- c()
res <- 1
for(i in 1:nrow(data_tibble)){
if(length(return_c) == 0||
(as.numeric(data_tibble[i,1]) > return_c[(res - 1) * 2 - 1]
&& as.numeric(data_tibble[i,2]) > return_c[(res - 1) * 2])){
return_c[res * 2 -1] <- as.numeric(data_tibble[i,1])
return_c[res * 2] <- as.numeric(data_tibble[i,2])
res <- res + 1
}else if(as.numeric(data_tibble[i,1]) > return_c[(res - 1) * 2 - 1]
&& as.numeric(data_tibble[i,2]) < return_c[(res - 1) * 2]){
change_index <- which(return_c[seq(2,res * 2,by = 2)] > as.numeric(data_tibble[i,2]))[1]
return_c[change_index] <- as.numeric(data_tibble[i,2])
return_c[change_index - 1] <- as.numeric(data_tibble[i,1])
}
}
return(length(return_c) %/% 2)
}
(envelop <- envelop[order(envelop$length,envelop$width),])
cat("该测试用例的叠加个数最大是",LIS.num(envelop))
以上代码就是R语言实现俄罗斯套娃问题的解题,借助LIS的动态规划思想,加以改造即可