📜  生成 1 到 N 的排列,每个元素的前缀最小值之和为 Y(1)

📅  最后修改于: 2023-12-03 15:11:13.144000             🧑  作者: Mango

生成排列使得前缀最小值之和为Y

本题是一个经典的数学优化问题。给定一个整数N,求长度为N的排列P,使得每个前缀之和的最小值等于给定的值Y。

方法

为了解决这个问题,我们可以使用贪心算法。我们从1-N的所有数中选择一个数,并将其放入排列的首位。然后,我们将剩余的数按照升序排序。我们接着选择下一位数字,使得前缀之和的最小值不小于我们希望的值Y。我们重复这个过程,直到所有数字都出现在排列中。

算法实现

下面是Golang实现的样例代码:

func permutation(n int, y int) []int {
    p := make([]int, n)
    for i := 0; i < n; i++ {
        p[i] = i + 1
    }
    for i := 0; i < n; i++ {
        if p[i] > 1 {
            swap(p, i, i-1)
        }
        min := p[i]
        for j := i + 1; j < n; j++ {
            if p[j] < min {
                min = p[j]
            }
            if min*(j-i+1)+sum(p, j+1, n) >= y {
                reverse(p, i, j)
                break
            }
        }
    }
    return p
}

func swap(p []int, i, j int) {
    p[i], p[j] = p[j], p[i]
}

func reverse(p []int, i, j int) {
    for i < j {
        swap(p, i, j)
        i++
        j--
    }
}

func sum(p []int, i, j int) int {
    s := 0
    for k := i; k < j; k++ {
        s += p[k]
    }
    return s
}
参考
  1. http://www.cnblogs.com/zpfbuaa/p/5905874.html
  2. https://www.geeksforgeeks.org/lexicographically-smallest-permutation-array-replace-array-element/
  3. https://www.jianshu.com/p/f9b7adea81de