leetcode6023 用地板覆盖过的最少最少白色砖块 hard
力扣74周双周赛的第四题
题目描述:
给你一个下标从 0 开始的 二进制 字符串 floor ,它表示地板上砖块的颜色。
floor[i] = ‘0’ 表示地板上第 i 块砖块的颜色是 黑色 。
floor[i] = ‘1’ 表示地板上第 i 块砖块的颜色是 白色 。
同时给你 numCarpets 和 carpetLen 。你有 numCarpets 条 黑色 的地毯,每一条 黑色 的地毯长度都为 carpetLen 块砖块。请你使用这些地毯去覆盖砖块,使得未被覆盖的剩余 白色 砖块的数目 最小 。地毯相互之间可以覆盖。
请你返回没被覆盖的白色砖块的 最少 数目。
示例 1:
输入:floor = "10110101", numCarpets = 2, carpetLen = 2
输出:2
解释:
上图展示了剩余 2 块白色砖块的方案。
没有其他方案可以使未被覆盖的白色砖块少于 2 块。
示例 2:
输入:floor = "11111", numCarpets = 2, carpetLen = 3
输出:0
解释:
上图展示了所有白色砖块都被覆盖的一种方案。
注意,地毯相互之间可以覆盖。
解法思路:
class Solution {
public int minimumWhiteTiles(String floor, int numCarpets, int carpetLen) {
//双dp数组,第一层对地板长度做dp,第二层对地毯块数做dp
//dp[i][j] 表示直到第i-1块地板用了j-1块地毯后没有覆盖的白砖所需要的最少砖块
int[][] dp = new int[floor.length() + 1][numCarpets + 1];
for (int i = 1; i <= floor.length(); i++) {
for (int j = 0; j <= numCarpets; j++) {
//两种转换过程:
//1、floor[i]没有被覆盖,dp[i][j]=dp[i-1][j] + floor.charAt(i - 1)-'0'
//2、floor[i]有被覆盖,dp[i][j]=dp[i-carpetLen][j-1]
//还要考虑到i > carpetLen是转换2的前提条件,否则需要返回0
dp[i][j] = Math.min(dp[i - 1][j] + floor.charAt(i - 1) - '0',
j > 0 ? i > carpetLen? dp[i-carpetLen][j-1] : 0 : Integer.MAX_VALUE);
}
}
return dp[floor.length()][numCarpets];
}
}
贪心算法涉及到的边界处理太多,容易出错。
运行结果: