题解 | #合唱队#

合唱队

https://www.nowcoder.com/practice/6d9d69e3898f45169a441632b325c7b4

package main

import (
	"fmt"
)

func main() {
	var n int
	fmt.Scan(&n)

	heights := make([]int, n)
	for i := 0; i < n; i++ {
		fmt.Scan(&heights[i])
	}

	// 计算从左到右的最长递增子序列
	left := make([]int, n)
	for i := 0; i < n; i++ {
		left[i] = 1
		for j := 0; j < i; j++ {
			if heights[j] < heights[i] && left[j]+1 > left[i] {
				left[i] = left[j] + 1
			}
		}
	}

	// 计算从右到左的最长递增子序列
	right := make([]int, n)
	for i := n - 1; i >= 0; i-- {
		right[i] = 1
		for j := n - 1; j > i; j-- {
			if heights[j] < heights[i] && right[j]+1 > right[i] {
				right[i] = right[j] + 1
			}
		}
	}

	// 找到最长的合唱队形长度
	maxLen := 0
	for i := 0; i < n; i++ {
		if left[i]+right[i]-1 > maxLen {
			maxLen = left[i] + right[i] - 1
		}
	}

	// 计算需要出列的同学数
	minOut := n - maxLen

	fmt.Println(minOut)
}

以下是一个使用Golang实现的解决方案:

package main

import (
	"fmt"
)

func main() {
	var n int
	fmt.Scan(&n)

	heights := make([]int, n)
	for i := 0; i < n; i++ {
		fmt.Scan(&heights[i])
	}

	// 计算最长递子序列(LIS)
	lis := longestIncreasingSubsequence(heights)

	// 计算最长减子序列(LDS)
	lds := longestDecreasingSubsequence(heights)

	// 找到最长合唱队形的长度
	maxLen := 0
	for i := 0; i < n; i++ {
		len := lis[i] + lds[i] - 1
		if len > maxLen {
			maxLen = len
		}
	}

	// 计算需要出列的同学目
	minOut := n - maxLen

	fmt.Println(minOut)
}

// 计算最长递增子序列
func longestIncreasingSubsequence(numsint) []int {
	n := len(nums)
	lis := make([], n)

	for i := 0; i < n; i++ {
		lis[i] = 1
		for j := 0; j < i; j++ {
			if nums[i] > nums[j] && lis[j]+1 > lis[i] {
				lis[i] = lis[j] + 1
			}
			}

	return lis
}

// 计算最长递减子列
func longestDecreasingSubsequence(nums []int) []int {
	n := len(nums)
	lds := makeint, n)

	for i := n - 1; i >= 0; i-- {
		lds[i] = 1
		for j := n - 1; j > i; j-- {
			if nums[i] > nums[j] && lds[j]+1 > lds[i] {
				lds[i] = lds[j] + 1
			}
		}
	}

	return lds
}

这个解方案使用动态规划的思想,分别计算最长递增子列(LIS)和最长递减子列(LDS)。然后通过遍历每个同学找到最长合唱队形的长度。最后,需要出列的同学数等于总人减去最长合队形的长度。

全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务