1.删除字符使字符串变好 (简单模拟略)
2.检查操作是否合法 (枚举)
枚举给出坐标的八个方向,并判断是否符合要求。
3.K 次调整数组大小浪费的最小总空间 (区间dp)
首先明确一点,要求到浪费的最小值,那么这k次调整肯定是用得越多,最后产生的浪费越少。将题目转化一下:将一个数组分为k+1段,使得每段产生的浪费值之和最小。其中每一段的浪费值为,该段最大的数*该段长度-该段总元素和.
dp[i][j]:将nums中前i个元素分为j段的最小浪费空间和
dp[i][j] = min{dp[k - 1][j - 1] + k到i这一段的浪费值之和}其中0<=k<=i 其中当k==0时dp[i][j]=0到i这一段的浪费值。 为了减少时间复杂度,首先需要预处理出所有线段的浪费值,这需要n^2,然后再用上述的状态转移方程进行转移,最终的答案就为dp[n - 1][k + 1].
func minSpaceWastedKResizing(nums []int, k int) int {
n := len(nums)
g := make([][]int, n)
for i := 0 ; i < len(g) ; i++ {
g[i] = make([]int, n)
}
for i := 0 ; i < n ; i++ {
maxVal := math.MinInt32
sum := 0
for j := i ; j < n ; j++ {
sum += nums[j]
if nums[j] > maxVal {
maxVal = nums[j]
}
g[i][j] = maxVal * (j - i + 1) - sum
}
}
dp := make([][]int, n)
for i := 0 ; i < len(dp) ; i++ {
dp[i] = make([]int, k + 2)
}
for i := 0 ; i < len(dp) ; i++ {
for j := 0 ; j < len(dp[i]) ; j++ {
dp[i][j] = math.MaxInt32
}
}
for i := 0 ; i < n ; i++ {
for j := 1 ; j < k + 2 ; j++ {
for t := 0 ; t <= i ; t++ {
if t == 0 {
dp[i][j] = min(dp[i][j], g[t][i])
} else {
dp[i][j] = min(dp[i][j], dp[t - 1][j - 1] + g[t][i])
}
}
}
}
return dp[n - 1][k + 1]
}
4.两个回文子字符串长度的最大乘积 (马拉车不想学)
这tm数据量就很离谱,必须用马拉车来做,普通dp过不了,不搞竞赛不想学这个玩意儿...