题解一(枚举)

枚举所有起点开始的子串,求出以 0 开头或以 1 开头的最小权值,并累加到结果中。

写法 1:

fun main(args: Array<String>) {
    val str = nextString()
    var ret = 0
    for (i in 0 until str.length) {
        var c0 = 0
        var c1 = 0
        for (j in i until str.length) {
            if ((str[j] == '0' && (j - i) % 2 == 0) || (str[j] == '1' && (j - i) % 2 == 1)) {
                c0++
            } else {
                c1++
            }
            ret += min(c0, c1)
        }
    }
    println(ret)
    done()
}

写法 2:

fun main(args: Array<String>) {
    val str = nextString()
    var ret = 0
    for (i in 0 until str.length) {
        var c0 = 0
        var c1 = 0
        for (j in i until str.length) {
            c0 += if (str[j] == "01"[(j - i) % 2]) 1 else 0
            c1 += if (str[j] == "10"[(j - i) % 2]) 1 else 0
            ret += min(c0, c1)
        }
    }
    println(ret)
    done()
}

复杂度分析:

  • 时间复杂度:O(n^2)
  • 空间复杂度:O(1)

题解二(区间 DP)

  • 定义: 定义 dp[i][j] 表示区间 [i, j] 的最小权值,考虑到以 0 或 1 开头的权值可能不同,再增加第三维度 [k] 表示以 0 和 1 结尾的最小权值;
  • 转移: 对于 [i, j] 区间来说,可以从 [i, j - 1] 区间转移过来,对于字符 str[j] 来说,有转换和不转换两种选择,那么有:
    • 转换:dp[i][j][x xor 1] = dp[i][j - 1][x] + 1
    • 不转换:dp[i][j][x] = dp[i][j - 1][x xor 1]
fun main(args: Array<String>) {
    val str = nextString()
    val n = str.length
    var ret = 0
    // dp[i][j][2] 表示 [i,j] 以 0 和 1 结尾的最小权值
    val dp = Array(n) { Array(n) { IntArray(2) } }
    for (i in 0 until n) {
        dp[i][i][0] = if (str[i] == '0') 0 else 1
        dp[i][i][1] = if (str[i] == '0') 1 else 0
    }
    for (len in 2..n) {
        for (i in 0..n - len) {
            val j = i + len - 1
            val x = str[j] - '0'
            dp[i][j][x] = dp[i][j - 1][x xor 1]
            dp[i][j][x xor 1] = dp[i][j - 1][x] + 1
            // println("len=$len, i=$i, j=$j, x=$x, sub=${str.substring(i, j + 1)} ${dp[i][j][x]}, ${dp[i][j][x xor 1]}")
            ret += Math.min(dp[i][j][x], dp[i][j][x xor 1])
        }
    }
    println(ret)
    done()
}

复杂度分析:

  • 时间复杂度:O(n^2) 一共有 n^2 个子状态,每个子状态的时间是 O(1),动态规划整体时间复杂度是 O(n^2);
  • 空间复杂度:O(n^2) DP 数组空间。