Java || Simple || Memiozation
```\nclass Solution {\n    int[] suff;\n    Integer[][] dp;\n    public int minimumWhiteTiles(String floor, int numCarpets, int carpetLen) {    \n        if (ca
```\nclass Solution {\n    int[] suff;\n    Integer[][] dp;\n    public int minimumWhiteTiles(String floor, int numCarpets, int carpetLen) {    \n        if (carpetLen == floor.length()) {\n            return 0;\n        }\n        dp = new Integer[floor.length()][numCarpets + 1];\n        //  suff[i] = number of white tiles in s[i....]\n\t\tsuff = cumulative(floor);\n        return helper(floor, numCarpets, carpetLen, 0);\n    }\n    \n\t//  normal suffix array\n    public int[] cumulative(String s) {\n        int[] suff = new int[s.length()];\n        suff[s.length() - 1] = (s.charAt(s.length() - 1) == \'0\' ? 0 : 1);\n        for (int i = s.length() - 2; i >= 0; i--) {\n            suff[i] = suff[i + 1] + (s.charAt(i) == \'0\' ? 0 : 1);\n        }\n        return suff;\n    }\n    \n    public int helper(String s, int n, int k, int idx) {\n        \n        //  no more floors remaining so no white carpets need to be covered\n        if (idx >= s.length()) {\n            return 0;\n        }\n        \n        if (dp[idx][n] != null) {\n            return dp[idx][n];\n        }\n        \n        //  floors remaining but carpets exhausted\n        if (n == 0) {\n            return suff[idx];\n        }\n        \n        //  this is already black skip this floor\n        if (s.charAt(idx) == \'0\') {\n            return helper(s, n, k, idx + 1);\n        }\n        \n        //  now we have two choices whether to leave this white\n        //  as it is or cover this in black\n        \n        \n        //  if covering this and any other black floor in range as black\n        int answer = helper(s, n - 1, k, idx + k);\n        \n        //  leaving this as white as it was\n        answer = Math.min(answer, helper(s, n, k, idx + 1) + 1);\n        return dp[idx][n] = answer;\n    }\n}\n
[]