C++/Python, dynamic programming solution with explanation
dp[i][j] is minimum number of visible white tiles in the first i tiles ([0, i]) which are coverd by j carpets.\nIf the tile is black, dp[i][j] = dp[i][j-1] + 1.
```dp[i][j]``` is minimum number of visible white tiles in the first ```i``` tiles ([0, i]) which are coverd by ```j``` carpets.\nIf the tile is black, ```dp[i][j] = dp[i][j-1] + 1```.\nIf the tile is white, we have 2 choices,\none is using a carpet to to cover it, ```dp[i][j] = dp[i-1][j-carpetLen]```.\nAnother is not to cover it, ```dp[i][j] = dp[i][j-1] + 1```.\nWe select minimum choice, ```dp[i][j] = min(dp[i][j-1] + (\'1\' == floor[j]), dp[i-1][j-carpetLen])```.\n\nAt first, there is no carpet, so ```dp[0][j]``` is number of white tiles in the first ```j``` tiles.\n\ntc and sc are O(numCarpets * len(floor))\n\n### python\n```python\nclass Solution:\n    def minimumWhiteTiles(self, floor: str, numCarpets: int, carpetLen: int) -> int:\n        size = len(floor)\n\t\t\n\t\t# floor are covered by carpets entirely\n        if numCarpets * carpetLen >= size: return 0\n\t\t\n        dp  = [[0] * size for _ in range(numCarpets+1)]\n\t\t\n\t\t# At first, there is no carpet\n\t\t# dp[0][j] is number of white tiles in the first j tiles\n        dp[0][0] = \'1\' == floor[0]\n        for i in range(1, size):\n            dp[0][i] = dp[0][i-1] + (\'1\' == floor[i])\n        \n        for i in range(1, numCarpets+1):\n\t\t\t# there have i carpets, it can covered i * carpetLen tiles, \n\t\t\t# so dp[i][0...i * carpetLen-1] are 0\n\t\t\t\n            for j in range(i * carpetLen, size):\n\t\t\t\t\n\t\t\t\t# min(not to cover, use a carpet to cover j-th tile)\n                dp[i][j] = min(dp[i][j-1] + (\'1\' == floor[j]), dp[i-1][j-carpetLen])\n        return dp[numCarpets][-1]\n```\n\n### c++\n```cpp\nclass Solution {\npublic:\n    int minimumWhiteTiles(string floor, int numCarpets, int carpetLen) {\n        int size = floor.size();\n        if (numCarpets * carpetLen >= size) return 0;\n        vector<vector<int>> dp (numCarpets+1, vector<int>(size));\n        dp[0][0] = (\'1\' == floor[0]);\n        for (int i = 1; i < size; i+=1) \n            dp[0][i] = dp[0][i-1] + (\'1\' == floor[i]); \n        for (int i = 1; i <= numCarpets; i+=1) {\n            for (int j = i * carpetLen; j < size; j+=1) {\n                dp[i][j] = min(dp[i][j-1] + (\'1\' == floor[j]), dp[i-1][j-carpetLen]); \n            }\n        }\n        return dp[numCarpets][size-1];\n    }\n};\n```\n### space optimization\nuse scrolling array.\n### python\n```python\nclass Solution:\n    def minimumWhiteTiles(self, floor: str, numCarpets: int, carpetLen: int) -> int:\n        size = len(floor)\n        if numCarpets * carpetLen >= size: return 0\n        dp  = [0] * size\n        dp[0] = \'1\' == floor[0]\n        for i in range(1, size):\n            dp[i] = dp[i-1] + (\'1\' == floor[i])\n        for i in range(1, numCarpets+1):\n            tmp = dp[:] # dp[i-1][j-carpetLen]\n            dp[i * carpetLen - 1] = 0 # notice that dp[j-1]\n            for j in range(i * carpetLen, size):\n                dp[j] = min(dp[j-1] + (\'1\' == floor[j]), tmp[j-carpetLen])\n        return dp[-1]\n```
['Dynamic Programming', 'C', 'Python']